Commit 553ab5f3 by jiang'yun

修改

parent ddf45ac5
...@@ -233,6 +233,12 @@ ...@@ -233,6 +233,12 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.github.thecoldwine</groupId>
<artifactId>sigrun</artifactId>
<version>0.4.5</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -36,7 +36,8 @@ public class MimeTypeUtils ...@@ -36,7 +36,8 @@ public class MimeTypeUtils
// 视频格式 // 视频格式
"mp4", "avi", "rmvb", "mp4", "avi", "rmvb",
// pdf // pdf
"pdf" }; "pdf",
"sgy","segy" };
public static String getExtension(String prefix) public static String getExtension(String prefix)
{ {
......
package com.ruoyi.project.dz;
import com.github.thecoldwine.sigrun.common.*;
import com.github.thecoldwine.sigrun.serialization.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;
public class SampleReadRoutine {
private static final Logger logger = LoggerFactory.getLogger(SampleReadRoutine.class.getName());
private static ParseProgressListener makeListener() {
return new ParseProgressListener() {
@Override
public void progress(long read) {
System.out.println("Progress changed to: " + read);
}
};
}
private static Set<ParseProgressListener> makeListenerSet() {
Set<ParseProgressListener> result = new HashSet<ParseProgressListener>();
result.add(makeListener());
return result;
}
public static BinaryHeaderFormat makeBinHeaderFormat() {
return BinaryHeaderFormatBuilder.aBinaryHeaderFormat()
.withLineNumberFormat(FormatEntry.create(4, 8))
.withSampleIntervalFormat(FormatEntry.create(16, 18))
.withSamplesPerDataTraceFormat(FormatEntry.create(20, 22))
.withDataSampleCodeFormat(FormatEntry.create(24, 26))
.withSegyFormatRevNumberFormat(FormatEntry.create(300, 302))
.withFixedLengthTraceFlagFormat(FormatEntry.create(302, 304))
.withNumberOf3200ByteFormat(FormatEntry.create(304, 306))
.build();
}
public static TraceHeaderFormat makeTraceHeaderFormat() {
return TraceHeaderFormatBuilder.aTraceHeaderFormat().
withEnsembleNumberFormat(FormatEntry.create(20, 24)).
withSourceXFormat(FormatEntry.create(72, 76)).
withSourceYFormat(FormatEntry.create(76, 80)).
withXOfCDPPositionFormat(FormatEntry.create(180, 184)).
withYOfCDPPositionFormat(FormatEntry.create(184, 188)).
withNumberOfSamplesFormat(FormatEntry.create(114, 116)).
build();
}
private static String tempPath = "D:\\qianhe\\file\\地震\\segy对比图\\line603_out_new_20250508.segy";
public static void main(String[] args) {
String path = tempPath;
if (path == null || path.isEmpty()) {
logger.error("Path is empty. Aborting");
System.exit(1);
}
logger.info(path);
try {
// Getting FileChannel for file.
FileChannel chan = new FileInputStream(path).getChannel();
// Create factory for particular SegY format
SEGYStreamFactory streamFactory = SEGYStreamFactory.create(
Charset.forName("Cp1047"),
makeBinHeaderFormat(),
makeTraceHeaderFormat());
final long startTime = System.currentTimeMillis();
// At this point reading actually started. EBCDIC and binary headers are parsed on
// object construction.
SEGYStream segyStream = streamFactory.makeStream(chan, makeListenerSet());
//
printTextHeader(segyStream.getTextHeader());
printBinHeaderInfo(segyStream.getBinaryHeader());
// Iterates over SegyFile. Stream is forward only and may be iterated only once.+
int i=1;
for (SeismicTrace trace : segyStream) {
if(i==1){
printTraceInfo(trace);
}
}
System.out.println(i);
final long timeEnd = System.currentTimeMillis() - startTime;
} catch (FileNotFoundException e) {
logger.error(e.getLocalizedMessage());
System.exit(2);
}
System.exit(0);
}
private static void printTextHeader(TextHeader header) {
System.out.println("Text Header info...");
for (String s : header.getContents()) {
System.out.println(s);
}
}
private static void printBinHeaderInfo(BinaryHeader binaryHeader) {
System.out.println("Binary Header info...");
System.out.println("Data sample code:" + binaryHeader.getDataSampleCode());
}
private static void printTraceInfo(SeismicTrace trace) {
System.out.println("Trace Header info...");
System.out.println("Number of samples: " + trace.getHeader().getNumberOfSamples());
System.out.println("Size of array: " + trace.getValues().length);
for(int i=0;i<trace.getValues().length;i++){
System.out.println(trace.getValues()[i]);
}
System.out.printf("Values: %.10f : %.10f%n", trace.getMin(), trace.getMax());
}
}
\ No newline at end of file
package com.ruoyi.project.dz.controller;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.project.dz.utils.Point;
import com.ruoyi.project.dz.utils.SegyReadUtil;
import com.ruoyi.project.dz.utils.SegyReader;
import com.ruoyi.project.dz.utils.SegyTextFileHeader;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* 地震
* 地震工区数据返回,segy文件的读取,切面数据返回
* @author ruoyi
*/
@RestController
@RequestMapping("/ndy/dz")
public class DzController extends BaseController
{
private static final Logger log = LoggerFactory.getLogger(DzController.class);
// @Autowired
// private ServerConfig serverConfig;
private static final String FILE_DELIMETER = ",";
// private static String tempPath = "/root/nandongyong/temp.Sgy";
// private static String tempPath = "C:\\ruoyi\\uploadPath\\11-VPVS.Sgy";
// private static String tempPath = "D:\\qianhe\\file\\地震\\cgm及配对的效果图\\line603_out.segy";
private static String tempPath = "D:\\qianhe\\file\\地震\\segy对比图\\line603_out_new_20250508.segy";
//
// private static String inPath = "/root/nandongyong/1-VPVS.Sgy";
// private static String inPath = "D:\\SoftWork\\2023-06-05 物地震\\地震\\1-VPVS.Sgy";
private static String inPath = "D:\\qianhe\\file\\地震\\segy对比图\\line603_out_new_20250508.segy";
/**
* 获取segy文件数据返回前端
* 文件流
*/
@GetMapping("/getSegyDataFile")
public void getSegyDataFile(String fileName, HttpServletResponse response, HttpServletRequest request)
{
try
{
if (!FileUtils.checkAllowDownload(fileName))
{
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = RuoYiConfig.getDownloadPath() + fileName;
filePath = "/root" + filePath;
// filePath = "D:\\SoftWork\\2023-06-05 物地震\\地震\\temp.Sgy";
filePath = tempPath;
System.out.println("/n/n filePath = " + filePath + "/n/n");
// String filePath = "/root/D:/home/ruoyi/uploadPath/avatar/2023/06/13/density.segy";
// String filePath = "D:\\SoftWork\\2023-06-05 钻井院难动用\\density.segy";
// String realFileName = "density.segy";
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
/**
* 获取工区坐标范围
*/
@GetMapping("/getGqInfo")
public SegyTextFileHeader getGqInfo(String fileName, HttpServletResponse response, HttpServletRequest request)
{
SegyReader reader = new SegyReader(inPath);
// SegyReader reader = new SegyReader("D:\\SoftWork\\2023-06-05 物地震\\地震\\1-VPVS.Sgy");
SegyTextFileHeader gq = null;
try {
gq = reader.getFileHeader3200();
} catch (Exception e) {
e.printStackTrace();
}
return gq;
}
/**
* 地震任意切面
* 传递一组坐标 代表一条折线 查询线上所有的点 然后查询对应位数的数据
*/
@RequestMapping("/getDzqm")
public void getDzqm(String fileName, @RequestBody String pointstr, HttpServletResponse response, HttpServletRequest request)
{
//pointstr = request.getParameter("pointstr");
List<Point> points = new ArrayList<>();
JSONArray json = JSONArray.parseArray(pointstr); // 首先把字符串转成 JSONArray 对象
if(json.size() > 0){
for(int i=0; i < json.size(); i++){
JSONObject job = json.getJSONObject(i); // 遍历 jsonarray 数组,把每一个对象转成 json 对象
int x = Integer.valueOf(String.valueOf(job.get("x"))); // 得到 每个对象中的属性值
int y = Integer.valueOf(String.valueOf(job.get("y"))); // 得到 每个对象中的属性值
Point tm = new Point();
tm.setX(x);
tm.setY(y);
points.add(tm);
}
}
fileName = inPath;
String outPath = tempPath;
// fileName = "D:\\SoftWork\\2023-06-05 物地震\\地震\\1-VPVS.Sgy";
// String outPath = "D:\\SoftWork\\2023-06-05 物地震\\地震\\temp.Sgy";
try {
SegyReadUtil.outFile(fileName, points, outPath);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, "realFileName");
FileUtils.writeBytes(outPath, response.getOutputStream());
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
/**
* RemoteSeismicDataSource
* 三维地震切面 服务器处理
* Example:
* http://loclahost:8080/seismicreader?json=%7B%22file%22:%22seismicdata/cdp_stack.sgy%22,%22type%22:%22info%22,%22query%22:%7B%7D,%22sourceId%22:-1%7D
* Where query string parameters:
* json:{"file":"seismicdata/cdp_stack.sgy","type":"info","query":{},"sourceId":-1}
**/
@RequestMapping("/qRemoteSeismicReader2222")
public void qRemoteSeismicReader(String json, HttpServletResponse response, HttpServletRequest request) {
System.out.println(json);
}
/******************************************************************************************************************/
/********************************** 地震三维切片 *****************************************************************/
/******************************************************************************************************************/
/**
*
* json: {"file":"data/seismic/Gullfaks_Amplitude.xgy","query":{},"sourceId":-1}
* */
@RequestMapping("/qRemoteSeismicReader/json/seismicdata")
public JSONObject seismicdata(String json) {
//接收参数
System.out.println(json);
JSONObject input = JSONObject.parseObject(json);
String file = input.getString("file");
String sourceId = input.getString("sourceId");
JSONObject query = input.getJSONObject("query");
//返回值
JSONObject output = new JSONObject();
output.put("version", "1");
output.put("displayName", "Gullfaks_Amplitude");
JSONArray keys = new JSONArray();
JSONObject k1 = new JSONObject();
k1.put("key", "INLINE");
k1.put("min", 187);
k1.put("max", 1026);
k1.put("increment", 1);
k1.put("sampleKey", false);
keys.add(k1);
JSONObject k2 = new JSONObject();
k2.put("key", "XLINE");
k2.put("min", 855);
k2.put("max", 1228);
k2.put("increment", 1);
k2.put("sampleKey", false);
keys.add(k2);
JSONObject k3 = new JSONObject();
k3.put("key", "Depth");
k3.put("min", 5402);
k3.put("max", 5901);
k3.put("increment", 0.58);
k3.put("sampleKey", true);
keys.add(k3);
output.put("keys", keys);
output.put("numberOfSamples", 857);
output.put("numberOfTraces", 314160);
output.put("startValue", 5402);
output.put("sampleRate", 0.58);
JSONObject statistics = new JSONObject();
statistics.put("min", -71);
statistics.put("max", 73);
statistics.put("mean", 7.7803535);
statistics.put("rms", 10.103634);
statistics.put("percentiles", new int[]{0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,10,10,11,11,11,11,11,
12,12,12,12,13,13,13,14,14,15,15,15,16,16,17,18,18,19,20,21,22,24,28,73});
output.put("statistics", statistics);
JSONArray gridCoordinates = new JSONArray();
JSONObject g1 = new JSONObject();
g1.put("values", new double[]{ 187, 855, 4429511, 14710962});
gridCoordinates.add(g1);
JSONObject g2 = new JSONObject();
g2.put("values", new double[]{ 187, 1228, 4438836, 14710962});
gridCoordinates.add(g2);
JSONObject g3 = new JSONObject();
g3.put("values", new double[]{ 1026, 855, 4429511, 14731937});
gridCoordinates.add(g3);
output.put("gridCoordinates", gridCoordinates);
JSONObject traceHeader = new JSONObject();
JSONArray fields = new JSONArray();
JSONObject fields_1 = new JSONObject();
fields_1.put("name", "TSSN");
fields_1.put("id", 0);
fields_1.put("type", "UInt");
fields_1.put("size", 4);
fields.add(fields_1);
traceHeader.put("fields", fields);
traceHeader.put("size", 144);
output.put("traceHeader", traceHeader_static);
JSONObject mapTraceHeader = new JSONObject();
JSONArray mapfields = new JSONArray();
JSONObject mapfields_1 = new JSONObject();
mapfields_1.put("name", "INLINE");
mapfields_1.put("id", 0);
mapfields_1.put("type", "Float");
mapfields_1.put("size", 4);
mapfields.add(mapfields_1);
JSONObject mapfields_2 = new JSONObject();
mapfields_2.put("name", "XLINE");
mapfields_2.put("id", 1);
mapfields_2.put("type", "Float");
mapfields_2.put("size", 4);
mapfields.add(mapfields_2);
JSONObject mapfields_3 = new JSONObject();
mapfields_3.put("name", "TraceNumber");
mapfields_3.put("id", 1100);
mapfields_3.put("type", "Double");
mapfields_3.put("size", 8);
mapfields.add(mapfields_3);
mapTraceHeader.put("fields", mapfields);
mapTraceHeader.put("size", 16);
output.put("mapTraceHeader", mapTraceHeader);
JSONArray outline = new JSONArray();
JSONArray outline_t = new JSONArray();
outline_t.add(new double[]{ 186.5, 854.5});
outline_t.add(new double[]{ 1026.5, 854.5});
outline_t.add(new double[]{ 1026.5, 1228.5});
outline_t.add(new double[]{ 186.5, 1228.5});
outline.add(outline_t);
output.put("outline", outline);
output.put("traceOrders", new int[]{ 1, 2});
output.put("units", 2);
output.put("zUnit", "m");
output.put("indexType", "VOLUME");
JSONObject volumeKeyNames = new JSONObject();
volumeKeyNames.put("i", "INLINE");
volumeKeyNames.put("j", "XLINE");
output.put("volumeKeyNames", volumeKeyNames);
output.put("volumeDefaultKeyNames", volumeKeyNames);
JSONObject xyKeyNames = new JSONObject();
xyKeyNames.put("xKeyName", "CDPX");
xyKeyNames.put("yKeyName", "CDPY");
xyKeyNames.put("multiplierType", 1);
xyKeyNames.put("multiplierFieldName", "LOC SCALER");
output.put("xyKeyNames", xyKeyNames);
output.put("epsgCode", "32631:unknown");
output.put("regular", false);
output.put("seismicFormatName", "Indexed-Segy");
JSONArray ebcdic = new JSONArray();
ebcdic.add(" C 1 SEGY OUTPUT FROM Petrel 2011.1 (64-bit) alpha Wednesday, November 03 2010 11");
output.put("ebcdic", ebcdic);
return output;
}
@RequestMapping("/qRemoteSeismicReader/json/seismicbinaryheader")
public void seismicbinaryheader(String json, HttpServletResponse response) {
//接收参数
System.out.println(json);
JSONObject input = JSONObject.parseObject(json);
String file = input.getString("file");
String outputType = input.getString("outputType");
//JSONObject query = input.getJSONObject("query");
// String fileName = "D:\\SoftWork\\2023-06-05 物地震\\地震\\1-VPVS.Sgy";
// String outPath = "D:\\SoftWork\\2023-06-05 物地震\\地震\\temp.Sgy";
String fileName = inPath;
String outPath = tempPath;
try {
byte[] data = SegyReadUtil.getFileHeaderByteArr400(fileName);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, "realFileName");
IOUtils.write(data, response.getOutputStream());
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
@RequestMapping("/qRemoteSeismicReader/json/seismicquery")
public JSONObject seismicquery(String json) {
//接收参数
System.out.println(json);
JSONObject input = JSONObject.parseObject(json);
String file = input.getString("file");
String sourceId = input.getString("sourceId");
String queryId = input.getString("queryId");
JSONObject query = input.getJSONObject("query");
JSONObject data = input.getJSONObject("data");
// query内容
JSONArray query_keys = query.getJSONArray("keys");
JSONObject query_options = query.getJSONObject("options");
JSONObject query_emptyTracesKey = query.getJSONObject("emptyTracesKey");
int query_keys_size = query_keys.size();
//返回值
JSONObject output = new JSONObject();
output.put("version", 1.1);
output.put("sections", 374);
output.put("numberOfSamples", 857);
output.put("numberOfTraces", 374);
output.put("startValue", 5402);
output.put("sampleRate", 0.58);
JSONObject statistics = new JSONObject();
statistics.put("min", -71);
statistics.put("max", 73);
statistics.put("mean", 7.7803535);
statistics.put("rms", 10.103634);
statistics.put("percentiles", new int[]{0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,10,10,11,11,11,11,11,
12,12,12,12,13,13,13,14,14,15,15,15,16,16,17,18,18,19,20,21,22,24,28,73});
output.put("statistics", statistics);
return output;
}
@RequestMapping("/qRemoteSeismicReader/json/seismictraces")
public void seismictraces(String json, HttpServletResponse response) {
//接收参数
System.out.println(json);
JSONObject input = JSONObject.parseObject(json);
String file = input.getString("file");
String outputType = input.getString("outputType");
//JSONObject query = input.getJSONObject("query");
// String fileName = "D:\\SoftWork\\2023-06-05 物地震\\地震\\1-VPVS.Sgy";
// String outPath = "D:\\SoftWork\\2023-06-05 物地震\\地震\\temp.Sgy";
String fileName = inPath;
String outPath = tempPath;
try {
byte[] data = SegyReadUtil.getTest(fileName);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, "realFileName");
IOUtils.write(data, response.getOutputStream());
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
@RequestMapping("/qRemoteSeismicReader/json/enumeratedtraces")
public void enumeratedtraces(String json, HttpServletResponse response) {
//接收参数
System.out.println(json);
JSONObject input = JSONObject.parseObject(json);
String file = input.getString("file");
String outputType = input.getString("outputType");
//JSONObject query = input.getJSONObject("query");
// String fileName = "D:\\SoftWork\\2023-06-05 物地震\\地震\\1-VPVS.Sgy";
// String outPath = "D:\\SoftWork\\2023-06-05 物地震\\地震\\temp.Sgy";
String fileName = inPath;
String outPath = tempPath;
try {
byte[] data = SegyReadUtil.getTest(fileName);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, "realFileName");
IOUtils.write(data, response.getOutputStream());
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
private String traceHeader_static = "{\n" +
" \"fields\": [\n" +
" {\n" +
" \"name\": \"TSSN\",\n" +
" \"id\": 0,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"FIELD REC\",\n" +
" \"id\": 1,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"FIELD TR\",\n" +
" \"id\": 2,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SHTPT ID\",\n" +
" \"id\": 3,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"CDP\",\n" +
" \"id\": 4,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"CDPTR\",\n" +
" \"id\": 5,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"TRACE ID\",\n" +
" \"id\": 6,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"VERT SUM\",\n" +
" \"id\": 7,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"HORZ SUM\",\n" +
" \"id\": 8,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"DATA USE\",\n" +
" \"id\": 9,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"OFFSET\",\n" +
" \"id\": 10,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"RCV ELEV\",\n" +
" \"id\": 11,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SRC ELEV\",\n" +
" \"id\": 12,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SRC DEPTH\",\n" +
" \"id\": 13,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"RCV DATUM\",\n" +
" \"id\": 14,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SRC DATUM\",\n" +
" \"id\": 15,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SRC WATER DEPTH\",\n" +
" \"id\": 16,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"RCV WATER DEPTH\",\n" +
" \"id\": 17,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"ELEVATION SCALER\",\n" +
" \"id\": 18,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"LOC SCALER\",\n" +
" \"id\": 19,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"SRCX\",\n" +
" \"id\": 20,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SRCY\",\n" +
" \"id\": 21,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"RCVX\",\n" +
" \"id\": 22,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"RCVY\",\n" +
" \"id\": 23,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"COORD UNITS\",\n" +
" \"id\": 24,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"WEATHER VEL\",\n" +
" \"id\": 25,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"SUBWEATHER VEL\",\n" +
" \"id\": 26,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"SRC UPHOLE TIME\",\n" +
" \"id\": 27,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"RCV UPHOLE TIME\",\n" +
" \"id\": 28,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"SRC STATIC CORR\",\n" +
" \"id\": 29,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"RCV STATIC CORR\",\n" +
" \"id\": 30,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"TOTAL STATIC CORR\",\n" +
" \"id\": 31,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"LAG A\",\n" +
" \"id\": 32,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"LAG B\",\n" +
" \"id\": 33,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"START TIME\",\n" +
" \"id\": 214,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"MUTE START\",\n" +
" \"id\": 34,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"MUTE END\",\n" +
" \"id\": 35,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"SAMPLES IN TRACE\",\n" +
" \"id\": 36,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"SAMPLE RATE\",\n" +
" \"id\": 37,\n" +
" \"type\": \"UShort\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"CDPX\",\n" +
" \"id\": 38,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"CDPY\",\n" +
" \"id\": 39,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"INLINE\",\n" +
" \"id\": 40,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"XLINE\",\n" +
" \"id\": 41,\n" +
" \"type\": \"Int\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SHTPT NUM\",\n" +
" \"id\": 42,\n" +
" \"type\": \"UInt\",\n" +
" \"size\": 4\n" +
" },\n" +
" {\n" +
" \"name\": \"SURF TIME SCALER\",\n" +
" \"id\": 43,\n" +
" \"type\": \"Short\",\n" +
" \"size\": 2\n" +
" },\n" +
" {\n" +
" \"name\": \"TraceNumber\",\n" +
" \"id\": 1100,\n" +
" \"type\": \"Double\",\n" +
" \"size\": 8\n" +
" }\n" +
" ],\n" +
" \"size\": 144\n" +
" }";
}
package com.ruoyi.project.dz.utils;
public class ByteUtil {
/**
* 转换short为byte
*
*/
public static Byte[] putShort(short s) {
Byte[] b =new Byte[2];;
b[1] = (byte) (s >> 8);
b[0] = (byte) (s >> 0);
return b;
}
/**
* 通过byte数组取到short
*
* @param b
* @param index
* 第⼏位开始取
* @return
*/
public static short getShort(byte[] b, int index) {
return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff));
}
/**
* 转换int为byte数组
*
*/
public static Byte[] putInt(int x) {
Byte[] bb =new Byte[4];
bb[ 3] = (byte) (x >> 24);
bb[2] = (byte) (x >> 16);
bb[1] = (byte) (x >> 8);
bb[0] = (byte) (x >> 0);
return bb;
}
/**
* 通过byte数组取到int
*
* @param bb
* @param index
* 第⼏位开始
* @return
*/
public static int getInt(byte[] bb, int index) {
return (int) ((((bb[index + 3] & 0xff) << 24)
| ((bb[index + 2] & 0xff) << 16)
| ((bb[index + 1] & 0xff) << 8) | ((bb[index + 0] & 0xff) << 0))); }
/**
* 转换long型为byte数组
*
* @param bb
* @param x
* @param index
*/
public static void putLong(byte[] bb, long x, int index) {
bb[index + 7] = (byte) (x >> 56);
bb[index + 6] = (byte) (x >> 48);
bb[index + 5] = (byte) (x >> 40);
bb[index + 4] = (byte) (x >> 32);
bb[index + 3] = (byte) (x >> 24);
bb[index + 2] = (byte) (x >> 16);
bb[index + 1] = (byte) (x >> 8);
bb[index + 0] = (byte) (x >> 0);
}
/**
* 通过byte数组取到long
*
* @param bb
* @param index
* @return
*/
public static long getLong(byte[] bb, int index) {
return ((((long) bb[index + 7] & 0xff) << 56)
| (((long) bb[index + 6] & 0xff) << 48)
| (((long) bb[index + 5] & 0xff) << 40)
| (((long) bb[index + 4] & 0xff) << 32)
| (((long) bb[index + 3] & 0xff) << 24)
| (((long) bb[index + 2] & 0xff) << 16)
| (((long) bb[index + 1] & 0xff) << 8) | (((long) bb[index + 0] & 0xff) << 0)); }
/**
* 字符到字节转换
*
* @param ch
* @return
*/
public static void putChar(byte[] bb, char ch, int index) {
int temp = (int) ch;
// byte[] b = new byte[2];
for (int i = 0; i < 2; i ++ ) {
bb[index + i] = new Integer(temp & 0xff).byteValue(); // 将最⾼位保存在最低位temp = temp >> 8; // 向右移8位
}
}
/**
* 字节到字符转换
*
* @param b
* @return
*/
public static char getChar(byte[] b, int index) {
int s = 0;
if (b[index + 1] > 0)
s += b[index + 1];
else
s += 256 + b[index + 0];
s *= 256;
if (b[index + 0] > 0)
s += b[index + 1];
else
s += 256 + b[index + 0];
char ch = (char) s;
return ch;
}
/**
* float转换byte
*
* @param bb
* @param x
* @param index
*/
public static void putFloat(byte[] bb, float x, int index) { // byte[] b = new byte[4];
int l = Float.floatToIntBits(x);
for (int i = 0; i < 4; i++) {
bb[index + i] = new Integer(l).byteValue();
l = l >> 8;
}
}
/**
* 通过byte数组取得float
*
* @param bb
* @param index
* @return
*/
public static float getFloat(byte[] b, int index) {
int l;
l = b[index + 0];
l &= 0xff;
l |= ((long) b[index + 1] << 8);
l &= 0xffff;
l |= ((long) b[index + 2] << 16);
l &= 0xffffff;
l |= ((long) b[index + 3] << 24);
return Float.intBitsToFloat(l);
}
/**
* double转换byte
*
* @param bb
* @param x
* @param index
*/
public static void putDouble(byte[] bb, double x, int index) { // byte[] b = new byte[8];
long l = Double.doubleToLongBits(x);
for (int i = 0; i < 4; i++) {
bb[index + i] = new Long(l).byteValue();
l = l >> 8;
}
}
/**
* 通过byte数组取得float
*
* @param bb
* @param index
* @return
*/
public static double getDouble(byte[] b, int index) { long l;
l = b[0];
l &= 0xff;
l |= ((long) b[1] << 8);
l &= 0xffff;
l |= ((long) b[2] << 16);
l &= 0xffffff;
l |= ((long) b[3] << 24);
l &= 0xffffffffl;
l |= ((long) b[4] << 32);
l &= 0xffffffffffl;
l |= ((long) b[5] << 40);
l &= 0xffffffffffffl;
l |= ((long) b[6] << 48);
l &= 0xffffffffffffffl;
l |= ((long) b[7] << 56);
return Double.longBitsToDouble(l);
}
}
\ No newline at end of file
package com.ruoyi.project.dz.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CodeUtil {
public static byte[] EToA = hexToBytes(getEDBToAsc());
public static byte[] AToE = hexToBytes(getAscToEDB());
public static String getAscToEDB() {
StringBuffer sb = new StringBuffer();
sb.append("00010203372D2E2F1605250B0C0D0E0F");
sb.append("101112133C3D322618193F271C1D1E1F");
sb.append("405A7F7B5B6C507D4D5D5C4E6B604B61");
sb.append("F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F");
sb.append("7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6");
sb.append("D7D8D9E2E3E4E5E6E7E8E9ADE0BD5F6D");
sb.append("79818283848586878889919293949596");
sb.append("979899A2A3A4A5A6A7A8A9C04FD0A107");
sb.append("202122232415061728292A2B2C090A1B");
sb.append("30311A333435360838393A3B04143EE1");
sb.append("41424344454647484951525354555657");
sb.append("58596263646566676869707172737475");
sb.append("767778808A8B8C8D8E8F909A9B9C9D9E");
sb.append("9FA0AAABAC4AAEAFB0B1B2B3B4B5B6B7");
sb.append("B8B9BABBBC6ABEBFCACBCCCDCECFDAdB");
sb.append("DCDDDEDFEAEBECEDEEEFFAFBFCFDFEFF");
return sb.toString();
}
public static String getEDBToAsc() {
StringBuffer sb = new StringBuffer();
sb.append("000102039C09867F978D8E0B0C0D0E0F");
sb.append("101112139D8508871819928F1C1D1E1F");
sb.append("80818283840A171B88898A8B8C050607");
sb.append("909116939495960498999A9B14159E1A");
sb.append("20A0A1A2A3A4A5A6A7A8D52E3C282B7C");
sb.append("26A9AAABACADAEAFB0B121242A293B5E");
sb.append("2D2FB2B3B4B5B6B7B8B9E52C255F3E3F");
sb.append("BABBBCBDBEBFC0C1C2603A2340273D22");
sb.append("C3616263646566676869C4C5C6C7C8C9");
sb.append("CA6A6B6C6D6E6F707172CBCCCDCECFD0");
sb.append("D17E737475767778797AD2D3D45BD6D7");
sb.append("D8D9DADBDCDDDEDFE0E1E2E3E45DE6E7");
sb.append("7B414243444546474849E8E9EAEBECED");
sb.append("7D4A4B4C4D4E4F505152EEEFF0F1F2F3");
sb.append("5C9F535455565758595AF4F5F6F7F8F9");
sb.append("30313233343536373839FAFBFCFDFEFF");
return sb.toString();
}
public static byte[] hexToBytes(char[] hex) {
int length = hex.length / 2;
byte[] raw = new byte[length];
for (int i = 0; i < length; i++) {
int high = Character.digit(hex[i * 2], 16);
int low = Character.digit(hex[i * 2 + 1], 16);
int value = (high << 4) | low;
if (value > 127)
value -= 256;
raw[i] = (byte) value;
}
return raw;
}
public static byte[] hexToBytes(String hex) {
return hexToBytes(hex.toCharArray());
}
/**
* byte :: ASCII->EBCDIC
*/
public static int ASCIIToEBCDIC(int ascii) {
return AToE[ascii & 0xff] & 0xff;
}
/**
* byte :: EBCDIC->ASCII
*/
public static int EBCDICToASCII(int ebcdic) {
return EToA[ebcdic & 0xff] & 0xff;
}
/**
* byte[] :: ASCII->EBCDIC
*/
public static byte[] ASCIIToEBCDIC(byte[] ascii) {
byte[] tobytes = new byte[ascii.length];
for (int i = 0; i < ascii.length; i++)
tobytes[i] = (byte) ASCIIToEBCDIC(ascii[i]);
return tobytes;
}
/**
* byte[] :: EBCDIC->ASCII
*/
public static byte[] EBCDICToASCII(byte[] ebcdic) {
byte[] tobytes = new byte[ebcdic.length];
for (int i = 0; i < ebcdic.length; i++)
tobytes[i] = (byte) EBCDICToASCII(ebcdic[i]);
return tobytes;
}
/**
* String :: ASCII->EBCDIC
*/
public static String ASCIIToEBCDIC(String ascii) throws Exception {
return new String(ASCIIToEBCDIC(ascii.getBytes("iso-8859-1")),
"iso-8859-1");
}
/**
* String :: EBCDIC->ASCII
*/
public static String EBCDICToASCII(String ebcdic) throws Exception {
return new String(EBCDICToASCII(ebcdic.getBytes("iso-8859-1")),
"iso-8859-1");
}
/**
* File :: ASCII->EBCDIC
*/
public static void ASCIIToEBCDIC(String fromfile, String tofile) {
try {
FileInputStream in = new FileInputStream(new File(fromfile));
FileOutputStream out = new FileOutputStream(new File(tofile));
int tempint, i = 0;
byte[] tempbytes = new byte[in.available()];
while ((tempint = in.read()) != -1)
tempbytes[i++] = (byte) tempint;
out.write(ASCIIToEBCDIC(tempbytes));
in.close();
out.close();
} catch (Exception e) {
System.out.println(e);
}
}
/**
* File :: EBCDIC->ASCII
*/
public static void EBCDICToASCII(String fromfile, String tofile) {
try {
FileInputStream in = new FileInputStream(new File(fromfile));
FileOutputStream out = new FileOutputStream(new File(tofile));
int tempint, i = 0;
byte[] tempbytes = new byte[in.available()];
while ((tempint = in.read()) != -1)
tempbytes[i++] = (byte) tempint;
out.write(EBCDICToASCII(tempbytes));
in.close();
out.close();
} catch (Exception e) {
System.out.println(e);
}
}
/**
* @param args
*/
public static void main(String[] args) {
try {
String srcStr = "Y2I10000CIBF01 0000000006000000000000000000000 ?DP START?TEST ACCOUNT"
+ "000348 ?0000000009387.93+?0000000000000.00+?0000000000000.00"
+ "+?0000000000000.00+?00000000?00000000?0.00000000+?00000000?0000000009387.93+?000"
+ "0000009387.93+?00000000000.00+?00000000000.00+?0000000000000.00+?0000000000000.0"
+ "0+?0000000000000.00+?0000000000000.00+?0000000009387.93+?0000000000001.00+?00000"
+ "00000001.82+?0000000000000.00+?0000000000000.00+?0000000000000.00+?0000000000000"
+ ".00+?0000000000000.00+?0000000000000.00+?0000000000000.00+?0000000000000.00+?000"
+ "006?END";
String srcStr1 = "3èò????????????@@???????????????????????????????@j?×@@@@@@?????j????@???????@???ó??@@@@@@@@@@@@@@@@@@@@@j?????????ùó?÷KùóNj?????????????K??Nj?????????????K??Nj?????????????K??Nj????????j????????j?K????????Nj????????j?????????ùó?÷KùóNj?????????ùó?÷KùóNj???????????K??Nj???????????K??Nj?????????????K??Nj?????????????K??Nj?????????????K??Nj?????????????K??Nj?????????ùó?÷KùóNj?????????????K??Nj?????????????K?òNj?????????????K??Nj?????????????K??Nj?????????????K??Nj?????????????K??Nj?????????????K??Nj?????????????K??Nj?????????????K??Nj?????????????K??Nj??????j???";
String outStr = ASCIIToEBCDIC(srcStr);
System.out.println(outStr);
System.out.println(EBCDICToASCII(srcStr1));
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.ruoyi.project.dz.utils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 获取两坐标之间的坐标点
* Created by wangjian on 2023/9/1.
*/
public class CoordinateUtil {
/**
* 依次传入两个点的XY坐标 返回两点之间的点列表
* */
public static List<Point> getPointBetweenTwo(int startX, int startY, int endX, int endY){
//目前可以处理 第二个点在第一个点右上、正右、正上、右下、
//不行的 正下、左下、正左、左上
//步骤1:获取起始坐标和结束坐标
// int startX = 10;
// int startY = 10;
// int endX = 10;
// int endY = 2;
//步骤2:计算两坐标之间的水平和垂直距离
int horizontalDistance = endX - startX;
int verticalDistance = endY - startY;
//步骤3:根据水平和垂直距离计算每一步的增量
//根据水平和垂直距离计算每一步的增量。增量可以通过将水平距离除以最大步数得到,
//同样地,垂直增量可以通过将垂直距离除以最大步数得到。为了简化,我们假设步数为10。
int maxSteps = horizontalDistance == 0 ? verticalDistance:horizontalDistance;//X轴坐标变化为0时,用Y计算
int abs_maxSteps = Math.abs(maxSteps);//绝对值 解决 第二个点在第一个点的 正下、左下、正左、左上 的情况
double horizontalIncrement = (double)horizontalDistance / abs_maxSteps;
double verticalIncrement = (double)verticalDistance / abs_maxSteps;
//步骤4:通过增量依次计算并输出每一个坐标点
List<Point> lp = new ArrayList<>();
for (int i = 0; i <= abs_maxSteps; i++) {
double currentX = startX + (i * horizontalIncrement);
double currentY = startY + (i * verticalIncrement);
Double bx = new BigDecimal(currentX).setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
Double by = new BigDecimal(currentY).setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
//System.out.println("坐标点 " + i + ": (" + bx + ", " + by + ")");
Point p = new Point();
p.setX(bx.intValue());
p.setY(by.intValue());
lp.add(p);
}
return lp;
}
}
package com.ruoyi.project.dz.utils;
/**
* Created by wangjian on 2023/9/4.
*/
public class Point {
private int x;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
package com.ruoyi.project.dz.utils;
/**
* segy文件格式异常
* @author dingyi
*
*/
public class SegyFileFormatException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public SegyFileFormatException(String msg){
super(msg);
}
}
package com.ruoyi.project.dz.utils;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 读取segy文件
* Created by wj on 2023/8/30.
*/
public class SegyReadUtil {
//EBCDIC文件头(3200字节)
private static int EBCDIC_FILE_HEADER_LENGTH = 3200;
//二进制文件头(400字节)
private static int BINARY_FILE_HEADER_LENGTH = 400;
//数据道道头 道头(Trace Header):长度:240 bytes;数据类型:32位、16位的整型;
//这部分包含每个道数据的元数据信息,如道序列号、道标识代码、坐标位置和记录参数等。
private static int TRACE_HEADER_LENGTH = 240;
/**
* EBCDIC文件头(3200字节) 由40个卡组成(例如:每行80个字符*40行),需要转换为ASCII码后才能显示。
* 主要用于记录与整个工区相关的信息,如施工单位、施工区、监理单位等。
**/
public static SegyTextFileHeader getFileHeader3200 (String filePath) throws IOException {
FileInputStream fis = null;
DataInputStream dis = null;
SegyTextFileHeader txtHdr = null;
try {
fis = new FileInputStream(filePath);
dis = new DataInputStream(fis);
// 首先读取前3200字节的文本头
byte[] buf = new byte[EBCDIC_FILE_HEADER_LENGTH];
dis.readFully(buf);
byte[] b = CodeUtil.EBCDICToASCII(buf);
txtHdr = new SegyTextFileHeader(b);
} catch (IOException e) {
System.out.println("读取文件头报错。");
e.printStackTrace();
} finally {
IOUtils.close(fis);
IOUtils.close(dis);
}
return txtHdr;
}
/**
* 二进制文件头(400字节)
* 用来存储描述SEG-Y文件的一些关键信息,包括SEG-Y文件的数据格式、采样点数、采样间隔等。
**/
public static SegyReelHdr getFileHeader400 (String filePath) throws IOException {
FileInputStream fis = null;
DataInputStream dis = null;
SegyReelHdr reelHdr = null;
try {
fis = new FileInputStream(filePath);
dis = new DataInputStream(fis);
// 首先读取前3200字节的文本头
byte[] buf = new byte[BINARY_FILE_HEADER_LENGTH];
dis.skipBytes(EBCDIC_FILE_HEADER_LENGTH);//跳过 开头 3200 个字节
dis.readFully(buf);
reelHdr = new SegyReelHdr(buf);
//判断是否有扩展卷头
if(reelHdr.has_extend_text_hdr_flag!=0){
//此时有3200字节的扩展原文文件头
//需要执行读取动作,此处暂空,以抛出异常为处理手段
System.out.println("存在扩展原文文件头,需要读取!");
}
} catch (IOException e) {
System.out.println("读取文件头报错。");
e.printStackTrace();
} finally {
IOUtils.close(fis);
IOUtils.close(dis);
}
return reelHdr;
}
/**
* 输出byte[]
**/
public static byte[] getFileHeaderByteArr400 (String filePath) throws IOException {
FileInputStream fis = null;
DataInputStream dis = null;
byte[] buf = new byte[BINARY_FILE_HEADER_LENGTH];
try {
fis = new FileInputStream(filePath);
dis = new DataInputStream(fis);
dis.skipBytes(EBCDIC_FILE_HEADER_LENGTH);//跳过 开头 3200 个字节
dis.readFully(buf);
} catch (IOException e) {
System.out.println("读取文件头报错。");
e.printStackTrace();
} finally {
IOUtils.close(fis);
IOUtils.close(dis);
}
return buf;
}
/**
* 根据指定线号道号获取道数据
* filePath 文件路径
* xh 线号 野外原始记录号 xline
* dh 道号 道集号 CDP等
* txtHdr 文件头信息 包含 线和道的范围 最大最小等信息
* reelHdr 卷头信息 包含 数据道采样点数 、 长度等信息
**/
public static SegyTrace getOneTraceByNo (String filePath, int xh, int dh, SegyTextFileHeader txtHdr,
SegyReelHdr reelHdr) throws IOException {
FileInputStream fis = null;
DataInputStream dis = null;
SegyTrace oneTrace = null;
try {
fis = new FileInputStream(filePath);
dis = new DataInputStream(fis);
//跳过文件头、卷头
dis.skipBytes(EBCDIC_FILE_HEADER_LENGTH);//跳过 开头 3200 个字节
dis.skipBytes(BINARY_FILE_HEADER_LENGTH);//跳过 卷头 400 个字节
// 根据卷头得出每一块数据集的大小 240+每道采样点数*根据编码格式获取的数据长度=每一道字符长度
int samples_per_trace = reelHdr.samples_per_trace;
int sample_length = reelHdr.getMultiple();
int dao_dataCount = TRACE_HEADER_LENGTH + reelHdr.samples_per_trace * reelHdr.getMultiple();
//根据线号、道号 以及 线号、道号的最小最大值(即范围) 来计算需要跳过的道数量
int xh_min = txtHdr.first_xline;
int xh_max = txtHdr.last_xline;
int dh_min = txtHdr.first_inline;
int dh_max = txtHdr.last_inline;
int skip_trace_num = (xh - xh_min) * (dh_max - dh_min + 1) + (dh - dh_min);//需要跳过的道数量
int skip_trace_length = skip_trace_num * dao_dataCount;//需要跳过的道长度
dis.skipBytes(skip_trace_length);//跳过
//读取一道数据返回 (分开读取道头和数据)
byte[] buf = new byte[TRACE_HEADER_LENGTH];
dis.readFully(buf);
oneTrace = new SegyTrace(buf);//道头
buf = new byte[reelHdr.samples_per_trace * reelHdr.getMultiple()];
dis.readFully(buf);
oneTrace.readDataInIBMFormat(buf);
} catch (IOException e) {
System.out.println("读取文件头报错。");
e.printStackTrace();
} catch (SegyFileFormatException e) {
System.out.println("读取卷头报错:数据编码格式及大小。");
e.printStackTrace();
} finally {
IOUtils.close(fis);
IOUtils.close(dis);
}
return oneTrace;
}
/**
* 根据指定线号道号获取道数据 获取byte数组
* filePath 文件路径
* xh 线号 野外原始记录号 xline
* dh 道号 道集号 CDP等
* txtHdr 文件头信息 包含 线和道的范围 最大最小等信息
* reelHdr 卷头信息 包含 数据道采样点数 、 长度等信息
**/
public static byte[] getOneTraceByteByNo (String filePath, int xh, int dh, SegyTextFileHeader txtHdr,
SegyReelHdr reelHdr) throws IOException {
FileInputStream fis = null;
DataInputStream dis = null;
SegyTrace oneTrace = null;
byte[] buf = null;
try {
fis = new FileInputStream(filePath);
dis = new DataInputStream(fis);
//跳过文件头、卷头
dis.skipBytes(EBCDIC_FILE_HEADER_LENGTH);//跳过 开头 3200 个字节
dis.skipBytes(BINARY_FILE_HEADER_LENGTH);//跳过 卷头 400 个字节
// 根据卷头得出每一块数据集的大小 240+每道采样点数*根据编码格式获取的数据长度=每一道字符长度
int samples_per_trace = reelHdr.samples_per_trace;
int sample_length = reelHdr.getMultiple();
int dao_dataCount = TRACE_HEADER_LENGTH + reelHdr.samples_per_trace * reelHdr.getMultiple();
//根据线号、道号 以及 线号、道号的最小最大值(即范围) 来计算需要跳过的道数量
int xh_min = txtHdr.first_xline;
int xh_max = txtHdr.last_xline;
int dh_min = txtHdr.first_inline;
int dh_max = txtHdr.last_inline;
int skip_trace_num = (xh - xh_min) * (dh_max - dh_min + 1) + (dh - dh_min);//需要跳过的道数量
int skip_trace_length = skip_trace_num * dao_dataCount;//需要跳过的道长度
dis.skipBytes(skip_trace_length);//跳过
//读取一道数据返回 (分开读取道头和数据)
buf = new byte[TRACE_HEADER_LENGTH + reelHdr.samples_per_trace * reelHdr.getMultiple()];
dis.readFully(buf);
} catch (IOException e) {
System.out.println("读取文件头报错。");
e.printStackTrace();
} catch (SegyFileFormatException e) {
System.out.println("读取卷头报错:数据编码格式及大小。");
e.printStackTrace();
} finally {
IOUtils.close(fis);
IOUtils.close(dis);
}
return buf;
}
/**
* byte数组合并
**/
public static byte[] byteMerger(byte[] bt1, byte[] bt2){
byte[] bt3 = new byte[bt1.length + bt2.length];
System.arraycopy(bt1, 0, bt3, 0, bt1.length);
System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
return bt3;
}
public static void outFile(String filePath, List<Point> points, String outPath) throws IOException, SegyFileFormatException {
SegyTextFileHeader txtHdr = SegyReadUtil.getFileHeader3200(filePath);
SegyReelHdr reelHdr = SegyReadUtil.getFileHeader400(filePath);
System.out.println("读取头文件");
FileInputStream fis = new FileInputStream(filePath);
DataInputStream dis = new DataInputStream(fis);
byte[] buf = new byte[3600];
dis.readFully(buf);
System.out.println("读取前端选点列表");
// List<Point> points = new ArrayList<>();
// Point p1 = new Point(); p1.setX(187); p1.setY(855); points.add(p1);
// Point p2 = new Point(); p2.setX(207); p2.setY(1228); points.add(p2);
// Point p3 = new Point(); p3.setX(1026); p3.setY(955); points.add(p3);
System.out.println(points);
if (points.size()>=2) {
for (int i = 0; i < points.size()-1; i++) {
Point nw = points.get(i);
Point nx = points.get(i+1);
System.out.println("坐标点 : (" + nw.getX() + ", " + nw.getY() + ") 与 (" + nx.getX() + ", " + nx.getY() + ")之间的点:");
List<Point> lp = CoordinateUtil.getPointBetweenTwo(nw.getX(), nw.getY(), nx.getX(), nx.getY());
for (int j = 0; j < lp.size(); j++) {
Point pp = lp.get(j);
System.out.println("坐标点 " + i + ": (" + pp.getX() + ", " + pp.getY() + ")");
byte[] tttrace = SegyReadUtil.getOneTraceByteByNo(filePath, pp.getX(), pp.getY(), txtHdr, reelHdr);
buf = SegyReadUtil.byteMerger(buf, tttrace);
}
}
}
FileOutputStream fos = null;
String pathName = outPath;//"D:\\SoftWork\\2023-06-05 物地震\\地震\\temp.Sgy";
File file = new File(pathName);
fos = new FileOutputStream(file);
fos.write(buf);
IOUtils.close(fos);
IOUtils.close(fis);
IOUtils.close(dis);
}
public static byte[] getTest(String filePath) throws IOException, SegyFileFormatException {
SegyTextFileHeader txtHdr = SegyReadUtil.getFileHeader3200(filePath);
SegyReelHdr reelHdr = SegyReadUtil.getFileHeader400(filePath);
FileInputStream fis = new FileInputStream(filePath);
DataInputStream dis = new DataInputStream(fis);
byte[] buf = new byte[0];
dis.skipBytes(3600);
List<Point> points = new ArrayList<>();
Point p1 = new Point(); p1.setX(187); p1.setY(855); points.add(p1);
Point p2 = new Point(); p2.setX(187); p2.setY(1228); points.add(p2);
if (points.size()>=2) {
for (int i = 0; i < points.size()-1; i++) {
Point nw = points.get(i);
Point nx = points.get(i+1);
System.out.println("坐标点 : (" + nw.getX() + ", " + nw.getY() + ") 与 (" + nx.getX() + ", " + nx.getY() + ")之间的点:");
List<Point> lp = CoordinateUtil.getPointBetweenTwo(nw.getX(), nw.getY(), nx.getX(), nx.getY());
for (int j = 0; j < lp.size(); j++) {
Point pp = lp.get(j);
System.out.println("坐标点 " + i + ": (" + pp.getX() + ", " + pp.getY() + ")");
byte[] tttrace = SegyReadUtil.getOneTraceByteByNo(filePath, pp.getX(), pp.getY(), txtHdr, reelHdr);
buf = SegyReadUtil.byteMerger(buf, tttrace);
}
}
}
IOUtils.close(fis);
IOUtils.close(dis);
return buf;
}
}
package com.ruoyi.project.dz.utils;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
//import org.sinoprobe.util.Util4JavaBean;
/**
* segy数据文件读取类
* 它包括了对segy文件所包含全部数据对象的封装
*
* @author dingyi
*
*/
public class SegyReader {
private String filePath;
private SegyTextFileHeader txtHdr;
private SegyReelHdr reelHdr;
private ArrayList<SegyTrace> traceList=new ArrayList<SegyTrace>();
/**
* 构造Segy读取对象
* @param filePath segy文件名,包括全路径
*/
public SegyReader(String filePath) {
super();
this.filePath = filePath;
}
public SegyTextFileHeader getFileHeader3200 () throws IOException, SegyFileFormatException {
FileInputStream fis = new FileInputStream(filePath);
DataInputStream dis = new DataInputStream(fis);
// 首先读取前3200字节的文本头
byte[] buf = new byte[3200];
dis.readFully(buf);
byte[] b = CodeUtil.EBCDICToASCII(buf);
txtHdr = new SegyTextFileHeader(b);
return txtHdr;
}
public void buildFromFile() throws IOException, SegyFileFormatException{
FileInputStream fis = new FileInputStream(filePath);
DataInputStream dis = new DataInputStream(fis);
// 首先读取前3200字节的文本头
byte[] buf = new byte[3200];
dis.readFully(buf);
byte[] b = CodeUtil.EBCDICToASCII(buf);
txtHdr = new SegyTextFileHeader(b);
//判断是否合法,即是否每一行均以C开头,如果不合法,那么,可能会是存在带头标签
// if(!txtHdr.isValid()){
// throw new SegyFileFormatException("卷头数据不是以C开头,可能存在标签对象,请尝试用另外方法读取!");
// }
//继续读取卷头数据
buf = new byte[400];
dis.readFully(buf);
reelHdr = new SegyReelHdr(buf);
//判断是否有扩展卷头
if(reelHdr.has_extend_text_hdr_flag!=0){
//此时有3200字节的扩展原文文件头
//需要执行读取动作,此处暂空,以抛出异常为处理手段
throw new SegyFileFormatException("存在扩展原文文件头,需要读取!");
}
dis.close();
fis.close();
outFile(filePath);
//测试
// SegyTextFileHeader txtHdr2 = SegyReadUtil.getFileHeader3200(filePath);
// SegyReelHdr reelHdr2 = SegyReadUtil.getFileHeader400(filePath);
// SegyTrace tttrace = SegyReadUtil.getOneTraceByNo(filePath, 187, 855, txtHdr, reelHdr);
// SegyTrace tttrace2 = SegyReadUtil.getOneTraceByNo(filePath, 187, 859, txtHdr, reelHdr);
// SegyTrace tttrace3 = SegyReadUtil.getOneTraceByNo(filePath, 188, 1225, txtHdr, reelHdr);
// SegyTrace tttrace4 = SegyReadUtil.getOneTraceByNo(filePath, 207, 1228, txtHdr, reelHdr);
// soutTrace(tttrace);
// soutTrace(tttrace2);
// soutTrace(tttrace3);
// soutTrace(tttrace4);
//继续读取道数据
//强制读取卷头所标记的
//for (int i = 0; i <reelHdr.traces_per_record; i++)
// while(dis.available()>0) {
// // 首先读取道头
// buf = new byte[240];
// dis.readFully(buf);
// SegyTrace oneTrace = new SegyTrace(buf);
// // 根据卷头和道头得出要读取的数据块的大小
// int dataCount = oneTrace.samples_in_this_trace * reelHdr.getMultiple();
// //读取道数据
// buf = new byte[dataCount];
// dis.readFully(buf);
// oneTrace.readDataInIBMFormat(buf);
// //添加到道列表中
// traceList.add(oneTrace);
// System.out.println("序号:" + traceList.size() + " 测线中道顺序号:" + oneTrace.trace_sequence_number_within_line
// + " 野外原始记录号:" + oneTrace.original_field_record_number
// + " 道集号:" + oneTrace.cdp_ensemble_number
// //+ " 道集的道数:" + oneTrace.trace_sequence_number_within_cdp_ensemble
// + " 该道采样点数:" + oneTrace.samples_in_this_trace
// + " 该道采样间隔:" + oneTrace.sample_intervall
// + " 震源坐标――X:" + oneTrace.x_source_coordinate
// + " 震源坐标――Y:" + oneTrace.y_source_coordinate
// //+ " 真实坐标值的因子:" + oneTrace.scalar_for_coordinates
// //+ " 产生该道的垂直叠加道数:" + oneTrace.number_of_vertically_summed_traces_yielding_this_trace
// //+ " 产生该道的水平叠加道数:" + oneTrace.number_of_horizontally_stacked_traced_yielding_this_trace
// );
// }
// System.out.println("读取道数据结束");
dis.close();
fis.close();
}
/**
* 得到原文文件头,文本格式
* @return
*/
public SegyTextFileHeader getTxtHdr() {
return txtHdr;
}
/**
* 得到卷(道集)头数据
* @return
*/
public SegyReelHdr getReelHdr() {
return reelHdr;
}
/**
* 得到道数据列表
* @return
*/
public ArrayList<SegyTrace> getTraceList() {
return traceList;
}
/**
* 得到测量到的最大最小值
* @return 顺序为min,Max
*/
public double[] getMinMaxValue(){
double[] minMax=new double[2];
minMax[0]=0;
minMax[1]=0;
for(SegyTrace t:traceList){
for(double d: t.data){
if(d>minMax[1])
minMax[1]=d;
if(d<minMax[0])
minMax[0]=d;
}
}
return minMax;
}
public static void main(String[] args) {
// SegyReader reader=new SegyReader("D:\\SoftWork\\2023-06-05 物地震\\地震2\\dy-sgy_dongyingdongbuall_3d_pstm2.Sgy");
SegyReader reader=new SegyReader("D:\\SoftWork\\2023-06-05 物地震\\地震\\1-VPVS.Sgy");
try {
reader.buildFromFile();
System.out.println("数据读取完成!开始构造vtk显示");
// //构造vtk界面
// final SimpleVTK2 vtkPanel=new SimpleVTK2(reader);
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
// JFrame frame = new JFrame("SimpleVTK");
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.getContentPane().setLayout(new BorderLayout());
// frame.getContentPane().add(vtkPanel);
// frame.setSize(640, 480);
// frame.setLocationRelativeTo(null);
// frame.setVisible(true);
// }
// });
//
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SegyFileFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void soutTrace(SegyTrace oneTrace){
System.out.println("序号:" //+ traceList.size()
+ " 测线中道顺序号:" + oneTrace.trace_sequence_number_within_line
+ " 野外原始记录号:" + oneTrace.original_field_record_number
+ " 道集号:" + oneTrace.cdp_ensemble_number
//+ " 道集的道数:" + oneTrace.trace_sequence_number_within_cdp_ensemble
+ " 该道采样点数:" + oneTrace.samples_in_this_trace
+ " 该道采样间隔:" + oneTrace.sample_intervall
+ " 震源坐标――X:" + oneTrace.x_source_coordinate
+ " 震源坐标――Y:" + oneTrace.y_source_coordinate
//+ " 真实坐标值的因子:" + oneTrace.scalar_for_coordinates
//+ " 产生该道的垂直叠加道数:" + oneTrace.number_of_vertically_summed_traces_yielding_this_trace
//+ " 产生该道的水平叠加道数:" + oneTrace.number_of_horizontally_stacked_traced_yielding_this_trace
);
}
public void outFile(String filePath) throws IOException, SegyFileFormatException {
System.out.println("读取头文件");
FileInputStream fis = new FileInputStream(filePath);
DataInputStream dis = new DataInputStream(fis);
byte[] buf = new byte[3600];
dis.readFully(buf);
System.out.println("读取前端选点列表");
List<Point> points = new ArrayList<>();
Point p = new Point();
p.setX(187); p.setY(1000);points.add(p);p = new Point();
p.setX(1026);p.setY(1000);points.add(p);p = new Point();
p.setX(687); p.setY(855); points.add(p);p = new Point();
p.setX(687); p.setY(1228);points.add(p);
System.out.println(points);
if (points.size()>=2) {
for (int i = 0; i < points.size()-1; i++) {
Point nw = points.get(i);
Point nx = points.get(i+1);
System.out.println("坐标点 : (" + nw.getX() + ", " + nw.getY() + ") 与 (" + nx.getX() + ", " + nx.getY() + ")之间的点:");
List<Point> lp = CoordinateUtil.getPointBetweenTwo(nw.getX(), nw.getY(), nx.getX(), nx.getY());
for (int j = 0; j < lp.size(); j++) {
Point pp = lp.get(j);
System.out.println("坐标点 " + i + ": (" + pp.getX() + ", " + pp.getY() + ")");
byte[] tttrace = SegyReadUtil.getOneTraceByteByNo(filePath, pp.getX(), pp.getY(), txtHdr, reelHdr);
buf = SegyReadUtil.byteMerger(buf, tttrace);
}
}
}
// byte[] tttrace = SegyReadUtil.getOneTraceByteByNo(filePath, 187, 855, txtHdr, reelHdr);
// byte[] all = SegyReadUtil.byteMerger(buf, tttrace);
// byte[] tttrace2 = SegyReadUtil.getOneTraceByteByNo(filePath, 187, 859, txtHdr, reelHdr);
// all = SegyReadUtil.byteMerger(all, tttrace2);
// byte[] tttrace3 = SegyReadUtil.getOneTraceByteByNo(filePath, 188, 1225, txtHdr, reelHdr);
// all = SegyReadUtil.byteMerger(all, tttrace3);
// byte[] tttrace4 = SegyReadUtil.getOneTraceByteByNo(filePath, 207, 1228, txtHdr, reelHdr);
// all = SegyReadUtil.byteMerger(all, tttrace4);
//
FileOutputStream fos = null;
String pathName = "D:\\SoftWork\\2023-06-05 物地震\\地震\\temp.Sgy";
File file = new File(pathName);
fos = new FileOutputStream(file);
fos.write(buf);
IOUtils.close(fos);
}
}
package com.ruoyi.project.dz.utils;
/**
* 表2. 二进制文件头
400字节二进制文件头
字节 描述
3201-3204 作业标识号
3205-3208 测线号。对3-D叠后数据而言,它将典型地包含纵向测线(In-line)号
3209-3212 卷号
3213-32145 每个道集的数据道数。叠前数据强制要求
3215-32165 每个道集的辅助道数。叠前数据强制要求
3217-32186 微秒(us)形式的采样间隔。叠前数据强制要求
3219-3220 微秒(us)形式的原始野外记录采样间隔
3221-32226 数据道采样点数。叠前数据强制要求
注释:二进制文件头中的采样间隔和采样点数应当是文件中地震数据的首要一组参数
3223-3224 原始野外记录每道采样点数
3225-32266 数据采样格式编码。叠前数据强制要求
1=4字节IBM浮点数
2=4字节,两互补整数
3=2字节,两互补整数
4=4字节带增益定点数(过时,不再使用)
5=4字节IEEE浮点数
6=现在没有使用
7=现在没有使用
8=1字节,两互补整数
3227-32287 道集覆盖次数――每个数据集的期望数据道数(例如CMP覆盖次数)。强烈推荐所有类型的数据使用
3229-32307 道分选码(即集合类型):
-1=其他(应在用户扩展文件头文本段中解释)
0=未知
1=同记录(未分选)
2=CDP道集
3=单次覆盖连续剖面
4=水平叠加
5=共炮点
6=共接收点
7=共偏移距
8=共中心点
9=共转换点
强烈推荐所有类型的数据使用
3231-3232 垂直求和码:
1=不求和
2=两次求和
M=M-1求和(M=2到32767)
3233-3234 起始扫描频率(Hz)
3235-3236 终止扫描频率(Hz)
3237-3238 扫描长度(ms)
3239-3240 扫描类型码:
1=线性
2=抛物线
3=指数
4=其他
3241-3242 扫描信道的道数
3243-3244 有斜坡时,以毫秒表示的扫描道起始斜坡长度(斜坡从零时刻开始,对这个长度有效)
3245-3246 以毫秒表示的扫描道终止斜坡长度(斜坡终止始于扫描长度减去斜坡结尾处的长度)
3247-3248 斜坡类型:
1=线性
2=cos2
3=其他
3249-3250 相关数据道:
1=无相关
2=相关
3251-3252 二进制增益恢复:
1=恢复
2=未恢复
3253-3254 振幅恢复方法:
1=无
2=球面扩散
3=自动增益控制
4=其他
3255-32567 测量系统:强烈推荐所有类型的数据使用。如文件中包含位置数据文本段,这条必须与位置数据文本段一致。如不同,最后位置数据文本段有控制权。
1=米
2=英尺
3257-3258 脉冲极化码:
1=压力增大或检波器向上运动在磁带上记作负数
2=压力减小或检波器向下运动在磁带上记作正数
3259-3260 可控源极化码:
地震信号滞后引导信号:
1=337.5°-22.5°
2=22.5°-67.5°
3=67.5°-112.5°
4=112.5°-157.5°
5=157.5°-202.5°
6=202.5°-247.5°
7=247.5°-292.5°
8=292.5°-337.5°
3261-3500 未赋值
3501-3502 6 SEG Y格式修订版号。这是一个16比特无符号数值,在第一和第二字节间有Q点。例如SEG Y修订版1.0,如文档定义,它将记录为0100 。此字段对所有SEG Y版本强制要求,尽管零值表示遵从1975年标准的“传统”SEG Y
3503-3504 6 固定长度道标志。1表示SEG Y文件中所有道确保具有相同的采样间隔和采样点数,即在原文文件头中3217-3218和3221-3222字节。0表示文件中的道长可能变化,此时道头中115-116字节的采样点数必须用来确认各道的实际长度。此字段对所有SEG Y版本强制要求,尽管零值表示遵从1975年标准的“传统”SEG Y
3505-3506 6 3200字节扩展原文文件头记录在二进制头后。0表示没有扩展原文文件头记录(即此文件无扩展原文文件头)。-1表示扩展原文文件头记录数可变,并且扩展原文文件头结尾用最终记录的一个文本段((SEG: ENDText))表示。正值表示有很多原文文件头。注意虽然具体的扩展原文文件头数目是个有用的信息,但是在写二进制头时它并不是总知道也不是强制要求在此记录正值。此字段对所有SEG Y版本强制要求,尽管零值表示遵从1975年标准的“传统”SEG Y
3507-3600 未赋值
5 此信息对叠前数据强制要求。
6 此信息对所有数据类型强制要求。
7 强烈建议此信息一直被记录。
* @author dingyi
*
*/
public class SegyReelHdr {
// 3201-3204 作业标识号
int job_id_number;
// 3205-3208 测线号。对3-D叠后数据而言,它将典型地包含纵向测线(In-line)号
int line_number;
// 3209-3212 卷号
int reel_number;
// 3213-3214 每个道集的数据道数。叠前数据强制要求
short traces_per_record;
// 3215-3216 每个道集的辅助道数。叠前数据强制要求
short aux_traces_per_record;
// 3217-3218 微秒(us)形式的采样间隔。叠前数据强制要求
short sample_data_interval_ms;
// 3219-3220 微秒(us)形式的原始野外记录采样间隔
short original_data_interval_ms;
// 3221-3222 数据道采样点数。叠前数据强制要求
// 注释:二进制文件头中的采样间隔和采样点数应当是文件中地震数据的首要一组参数
short samples_per_trace;
// 3223-3224 原始野外记录每道采样点数
short original_samples_per_trace;
// 3225-3226 数据采样格式编码。叠前数据强制要求
/**
* 1=4字节IBM浮点数 2=4字节,两互补整数 3=2字节,两互补整数 4=4字节带增益定点数(过时,不再使用) 5=4字节IEEE浮点数
* 6=现在没有使用 7=现在没有使用 8=1字节,两互补整数
*/
short data_sample_format_code;// 数据采样格式编码
// 3227-32287 道集覆盖次数――每个数据集的期望数据道数(例如CMP覆盖次数)。强烈推荐所有类型的数据使用
short CDP_fold;
// 3229-32307 道分选码(即集合类型):
/**
* -1=其他(应在用户扩展文件头文本段中解释) 0=未知 1=同记录(未分选) 2=CDP道集 3=单次覆盖连续剖面 4=水平叠加 5=共炮点
* 6=共接收点 7=共偏移距 8=共中心点 9=共转换点 强烈推荐所有类型的数据使用
*/
short trace_sorting_code;// 3229-32307 道分选码(即集合类型):
// 3231-3232 垂直求和码:
/*
* 1=不求和 2=两次求和 … M=M-1求和(M=2到32767)
*/
short vertical_sum_code;
// 3233-3234 起始扫描频率(Hz)
short sweep_frequency_start_hz;
// 3235-3236 终止扫描频率(Hz)
short sweep_frequency_end_hz;
// 3237-3238 扫描长度(ms)
short sweep_length_ms;
// 3239-3240 扫描类型码:
/**
* 1=线性 2=抛物线 3=指数 4=其他
*/
short sweep_type_code;
// 3241-3242 扫描信道的道数
short trace_number_of_sweep_channel;
// 3243-3244 有斜坡时,以毫秒表示的扫描道起始斜坡长度(斜坡从零时刻开始,对这个长度有效)
short sweep_trace_taper_length_start_ms;
// 3245-3246 以毫秒表示的扫描道终止斜坡长度(斜坡终止始于扫描长度减去斜坡结尾处的长度)
short sweep_trace_taper_length_end_ms;
/**
* 3247-3248 斜坡类型: 1=线性 2=cos2 3=其他
*/
short taper_type_code;
// 3249-3250 相关数据道:
// 1=无相关
// 2=相关
short correlated_data_traces_flag;
/**
* 3251-3252 二进制增益恢复: 1=恢复 2=未恢复
**/
short binary_gain_recovered_flag;
/**
* 3253-3254 振幅恢复方法: 1=无 2=球面扩散 3=自动增益控制 4=其他*
*/
short amplitude_recovery_method_code;
/**
* 3255-32567
* 测量系统:强烈推荐所有类型的数据使用。如文件中包含位置数据文本段,这条必须与位置数据文本段一致。如不同,最后位置数据文本段有控制权。 1=米
* 2=英尺
**/
short measurement_system;
/**
* 3257-3258 脉冲极化码: 1=压力增大或检波器向上运动在磁带上记作负数 2=压力减小或检波器向下运动在磁带上记作正数
**/
short impulse_signal_polarity;
/**
* 3259-3260 可控源极化码: 地震信号滞后引导信号: 1=337.5°-22.5° 2=22.5°-67.5° 3=67.5°-112.5°
* 4=112.5°-157.5° 5=157.5°-202.5° 6=202.5°-247.5° 7=247.5°-292.5°
* 8=292.5°-337.5°
**/
short vibratory_polarity_code;
// 3261-3500 未赋值
// 3501-3502 6 SEG Y格式修订版号。这是一个16比特无符号数值,在第一和第二字节间有Q点。例如SEG
// Y修订版1.0,如文档定义,它将记录为0100 。此字段对所有SEG Y版本强制要求,尽管零值表示遵从1975年标准的“传统”SEG Y
short segy_version;
// 3503-3504 6 固定长度道标志。1表示SEG
// Y文件中所有道确保具有相同的采样间隔和采样点数,即在原文文件头中3217-3218和3221-3222字节。0表示文件中的道长可能变化,此时道头中115-116字节的采样点数必须用来确认各道的实际长度。此字段对所有SEG
// Y版本强制要求,尽管零值表示遵从1975年标准的“传统”SEG Y
short fix_length_trace_flag;
// 3505-3506 6
// 3200字节扩展原文文件头记录在二进制头后。0表示没有扩展原文文件头记录(即此文件无扩展原文文件头)。-1表示扩展原文文件头记录数可变,并且扩展原文文件头结尾用最终记录的一个文本段((SEG:
// ENDText))表示。正值表示有很多原文文件头。注意虽然具体的扩展原文文件头数目是个有用的信息,但是在写二进制头时它并不是总知道也不是强制要求在此记录正值。此字段对所有SEG
// Y版本强制要求,尽管零值表示遵从1975年标准的“传统”SEG Y
short has_extend_text_hdr_flag;// 如果不为0,则有扩展的3200个标头
// 3507-3600 未赋值
public SegyReelHdr(byte[] b) {
int i = 0;
job_id_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 4;
line_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 8;
reel_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 12;
traces_per_record = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 14;
aux_traces_per_record = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 16;
sample_data_interval_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 18;
original_data_interval_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 20;
samples_per_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 22;
original_samples_per_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 24;
data_sample_format_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 26;
CDP_fold = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 28;
trace_sorting_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 30;
vertical_sum_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 32;
sweep_frequency_start_hz = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 34;
sweep_frequency_end_hz = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 36;
sweep_length_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 38;
sweep_type_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 40;
trace_number_of_sweep_channel = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 42;
sweep_trace_taper_length_start_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 44;
sweep_trace_taper_length_end_ms = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 46;
taper_type_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 48;
correlated_data_traces_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 50;
binary_gain_recovered_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 52;
amplitude_recovery_method_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 54;
measurement_system = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 56;
impulse_signal_polarity = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 58;
vibratory_polarity_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
// 3261-3500 未赋值
i = 300;
segy_version = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 302;
fix_length_trace_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 304;
has_extend_text_hdr_flag = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
// 3507-3600 未赋值
}
/**
* 得到编码格式对应的倍数
* 依据2002年segy数据规范
*
* 1=4字节IBM浮点数 2=4字节,两互补整数 3=2字节,两互补整数 4=4字节带增益定点数(过时,不再使用) 5=4字节IEEE浮点数
* 6=现在没有使用 7=现在没有使用 8=1字节,两互补整数
*/
public int getMultiple() throws SegyFileFormatException {
switch (this.data_sample_format_code) {
case 1:
case 2:
case 4:
case 5:
return 4;
case 3:
return 2;
case 8:
return 1;
}
throw new SegyFileFormatException("编码类型参数错误");
}
}
package com.ruoyi.project.dz.utils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.domain.BaseEntity;
import java.util.ArrayList;
/**
* 每个segy文件的卷头数据
* 对应2002年segy数据规范
*
*
* @author dingyi
*
*/
public class SegyTextFileHeader extends BaseEntity {
private ArrayList<String> txtHeader=new ArrayList<String>(40);
// C 3 First inline:855 Last inline:1228
int first_inline;//第一个纵向测线
int last_inline;//最后一个纵向测线
// C 4 First xline:187 Last xline:1026
int first_xline;//第一个横向测线
int last_xline;//最后一个横向测线
// C 5 xmin:14710960.00 xmax:14731940.00 inline spacing:25.00
Double xmin;//最小X坐标
Double xmax;//最大X坐标
Double inline_spacing;//纵向测线间隔
// C 6 ymin:4429512.00 ymax:14731940.00 inline spacing:25.00
Double ymin;//最小y坐标
Double ymax;//最大y坐标
Double inline_spacing_hx;//横向测线间隔
// C 7 Time min(ms):3590.00 max:3804.00 delta:0.25
// C 8
// C 9
// C10 Amplitude min:1.67 max:1.87
// C11 Trace sample format: IBM_FLOAT(1)
// C12 Coordinate scale factor:1
// C13
// C14 Binary header locations:
// C15 Sample interval : bytes 17-18
// C16 Number of samples per trace : bytes 21-22
// C17 Trace date format : bytes 25-26
// C18
// C19 Trace header locations:
// C20 Inline number : bytes 9-12
// C21 Xline number : bytes 21-24
// C22 Coordinate scale factor : bytes 71-72
// C23 X coordinate : bytes 73-76
// C24 Y coordinate : bytes 77-80
// C25 Trace start time/depth : bytes 109-110
// C26 Number of samples per trace : bytes 115-116
// C27 Sample interval : bytes 117-118
/**
* 根据读到的字节流构造卷头对象
* @param b 字节流
*/
public SegyTextFileHeader(byte[] b){
for(int i=0;i<40;i++){
StringBuffer sb=new StringBuffer(80);
for(int j=0;j<80;j++){
sb.append((char)b[i*80+j]);
}
txtHeader.add(i,sb.toString());
getInfo(sb.toString());
}
}
/**
* 判断卷头数据是否有效
* 依据2002年segy数据规范
* 判断依据:每一行均以大写C开头
* @return
*/
public boolean isValid(){
for(String s:txtHeader){
if(!s.startsWith("C"))
return false;
}
return true;
}
public void getInfo(String str){
if (StringUtils.isNotEmpty(str) && str.length() > 4 && str.startsWith("C 3 ")) {
String s2 = str.substring(4, str.length()); //去掉 "C 1 " 这些开头
String param_name_1 = s2.substring(0, s2.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_1 = s2.substring(s2.indexOf(":") + 1, s2.indexOf(" ", s2.indexOf(":")));//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_1 + " : " + param_value_1);
first_inline = Integer.valueOf(param_value_1);
//第二个参数
String s3 = s2.substring(s2.indexOf(" ", s2.indexOf(":")) + 1, s2.length());//第一个:之后第一个空格的位置 往后开始截取
s3 = s3.trim();
String param_name_2 = s3.substring(0, s3.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_2 = s3.substring(s3.indexOf(":") + 1, s3.length());//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_2 + " : " + param_value_2);
last_inline = Integer.valueOf(param_value_2);
}
if (StringUtils.isNotEmpty(str) && str.length() > 4 && str.startsWith("C 4 ")) {
String s2 = str.substring(4, str.length()); //去掉 "C 1 " 这些开头
String param_name_1 = s2.substring(0, s2.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_1 = s2.substring(s2.indexOf(":") + 1, s2.indexOf(" ", s2.indexOf(":")));//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_1 + " : " + param_value_1);
first_xline = Integer.valueOf(param_value_1);
//第二个参数
String s3 = s2.substring(s2.indexOf(" ", s2.indexOf(":")) + 1, s2.length());//第一个:之后第一个空格的位置 往后开始截取
s3 = s3.trim();
String param_name_2 = s3.substring(0, s3.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_2 = s3.substring(s3.indexOf(":") + 1, s3.length());//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_2 + " : " + param_value_2);
last_xline = Integer.valueOf(param_value_2);
}
if (StringUtils.isNotEmpty(str) && str.length() > 4 && str.startsWith("C 5 ")) {
String s2 = str.substring(4, str.length()); //去掉 "C 1 " 这些开头
String param_name_1 = s2.substring(0, s2.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_1 = s2.substring(s2.indexOf(":") + 1, s2.indexOf(" ", s2.indexOf(":")));//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_1 + " : " + param_value_1);
xmin = Double.valueOf(param_value_1);
//第二个参数
String s3 = s2.substring(s2.indexOf(" ", s2.indexOf(":")) + 1, s2.length());//第一个:之后第一个空格的位置 往后开始截取
s3 = s3.trim();
String param_name_2 = s3.substring(0, s3.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_2 = s3.substring(s3.indexOf(":") + 1, s3.indexOf(" ", s3.indexOf(":")));//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_2 + " : " + param_value_2);
xmax = Double.valueOf(param_value_2);
//第三个参数
String s4 = s3.substring(s3.indexOf(" ", s3.indexOf(":")) + 1, s3.length());//第一个:之后第一个空格的位置 往后开始截取
s4 = s4.trim();
String param_name_3 = s4.substring(0, s4.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_3 = s4.substring(s4.indexOf(":") + 1, s4.length());//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_3 + " : " + param_value_3);
inline_spacing = Double.valueOf(param_value_3);
}
if (StringUtils.isNotEmpty(str) && str.length() > 4 && str.startsWith("C 6 ")) {
String s2 = str.substring(4, str.length()); //去掉 "C 1 " 这些开头
String param_name_1 = s2.substring(0, s2.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_1 = s2.substring(s2.indexOf(":") + 1, s2.indexOf(" ", s2.indexOf(":")));//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_1 + " : " + param_value_1);
ymin = Double.valueOf(param_value_1);
//第二个参数
String s3 = s2.substring(s2.indexOf(" ", s2.indexOf(":")) + 1, s2.length());//第一个:之后第一个空格的位置 往后开始截取
s3 = s3.trim();
String param_name_2 = s3.substring(0, s3.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_2 = s3.substring(s3.indexOf(":") + 1, s3.indexOf(" ", s3.indexOf(":")));//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_2 + " : " + param_value_2);
ymax = Double.valueOf(param_value_2);
//第三个参数
String s4 = s3.substring(s3.indexOf(" ", s3.indexOf(":")) + 1, s3.length());//第一个:之后第一个空格的位置 往后开始截取
s4 = s4.trim();
String param_name_3 = s4.substring(0, s4.indexOf(":"));//获取一个属性名称 : 前的内容
String param_value_3 = s4.substring(s4.indexOf(":") + 1, s4.length());//之后到空格前的内容
System.out.println(" 读取内容 " + param_name_3 + " : " + param_value_3);
inline_spacing_hx = Double.valueOf(param_value_3);
}
}
public int getFirst_inline() {
return first_inline;
}
public void setFirst_inline(int first_inline) {
this.first_inline = first_inline;
}
public int getLast_inline() {
return last_inline;
}
public void setLast_inline(int last_inline) {
this.last_inline = last_inline;
}
public int getFirst_xline() {
return first_xline;
}
public void setFirst_xline(int first_xline) {
this.first_xline = first_xline;
}
public int getLast_xline() {
return last_xline;
}
public void setLast_xline(int last_xline) {
this.last_xline = last_xline;
}
public Double getXmin() {
return xmin;
}
public void setXmin(Double xmin) {
this.xmin = xmin;
}
public Double getXmax() {
return xmax;
}
public void setXmax(Double xmax) {
this.xmax = xmax;
}
public Double getInline_spacing() {
return inline_spacing;
}
public void setInline_spacing(Double inline_spacing) {
this.inline_spacing = inline_spacing;
}
public Double getYmin() {
return ymin;
}
public void setYmin(Double ymin) {
this.ymin = ymin;
}
public Double getYmax() {
return ymax;
}
public void setYmax(Double ymax) {
this.ymax = ymax;
}
public Double getInline_spacing_hx() {
return inline_spacing_hx;
}
public void setInline_spacing_hx(Double inline_spacing_hx) {
this.inline_spacing_hx = inline_spacing_hx;
}
}
package com.ruoyi.project.dz.utils;
/**
* Segy道
* 包括道头和道数据
* 参照Segy 2002年的标准编写
* 下面是2002年标准中道头数据的说明
*
*
* 表3 道头
240字节道头
字节 描述
1-4 测线中道顺序号――若一条测线有若干SEG Y文件号数递增。强烈推荐所有类型的数据使用
5-8 SEG Y文件中道顺序号――每个文件以道顺序1开始。
9-12 野外原始记录号。强烈推荐所有类型的数据使用
13-16 野外原始记录的道号。强烈推荐所有类型的数据使用
17-20 震源点号――当在相同有效地表位置多于一个记录时使用。建议在道头197-202字节定义新的条目用于炮点号。
21-24 道集号(即CDP,CMP,CRP等)
25-28 道集的道数――每个道集从道号1开始
29-30 道识别码:
-1=其他
0=未知
1=地震数据
2=死道
3=哑道
4=时断
5=井口
6=扫描
7=定时
8=水断
9=近场枪信号
10=远场枪信号
11=地震压力传感器
12=多分量地震传感器――垂直分量
13=多分量地震传感器――横向分量
14=多分量地震传感器――纵向分量
15=旋转多分量地震传感器――垂直分量
16=旋转多分量地震传感器――切向分量
17=旋转多分量地震传感器――径向分量
18=可控源反应质量
19=可控源底盘
20=可控源估计地面力
21=可控源参考
22=时间速度对
23…N=选用,(最大N=32767)
强烈推荐所有类型的数据使用
31-32 产生该道的垂直叠加道数。(1是一道,2是两道求和,…)
33-34 产生该道的水平叠加道数。(1是一道,2是两道求和,…)
35-36 数据用途:
1=生产
2=试验
37-40 从震源中心点到检波器组中心的距离(若与炮激发线方向相反取负)
41-44 检波器组高程(所有基准以上高程为正,以下为负) 道头中69-70字节的因子应用于这些数值。在二进制文件头3255-3256字节指定单位为英尺或米。垂直基准应通过位置数据文本段定义(见D-1节)。
45-48 震源地表高程
49-52 震源距地表深度(正数)
53-56 检波器组基准高程
57-60 震源基准高程
61-64 震源水深
65-68 检波器组水深
69-70 应用于所有在道头41-68字节给定的真实高程和深度的因子。因子=1,+10,+100,或+1000。若为正,因子为乘数;若为负,因子为除数。
71-72 应用于所有在道头73-88字节和181-188字节给定的真实坐标值的因子。因子=1,+10,+100,或+1000。若为正,因子为乘数;若为负,因子为除数。
73-76 震源坐标――X 参考坐标系应通过扩展头位置数据文本段识别(见D-1节)。
若坐标单位为弧度秒、小数度或度/分/秒(DMS),X值代表经度,Y值代表纬度。正值代表格林威治子午线以东或赤道以北,负值代表南或西。
77-80 震源坐标――Y
81-84 检波器组坐标――X
85-88 检波器组坐标――Y
89-90 坐标单位:
1=长度(米或英尺)
2=弧度秒
3=小数度
4=度,分,秒(DMS)
注意:为编码±DDDMMSS 89-90字节等于±DDD*104+MM*102+SS,71-72字节设置为1;为编码±DDDMMSS 89-90字节等于±DDD*106+MM*104+SS*102,71-72字节设置为-100。
91-92 风化层速度(如二进制文件头3255-3256字节指明的ft/s或m/s)
93-94 风化层下速度(如二进制文件头3255-3256字节指明的ft/s或m/s)
接表3 道头
95-96 震源处井口时间(毫秒) 毫秒表示的时间需应用道头215-216字节指定的因子。
97-98 检波器组处井口时间(毫秒)
99-100 震源的静校正量(毫秒)
101-102 检波器组的校正量(毫秒)
103-104 应用的总静校正量(毫秒)(如没有应用静校正量为零)
105-106 延迟时间A――以毫秒表示的240字节道识别头的结束和时间断点之间的时间。当时间断点出现在头之后,该值为正;当时间断点出现在头之前,该值为负。时间断点是最初脉冲,它由辅助道记录或由其他记录系统指定。
107-108 延迟时间B――以毫秒表示的时间断点到能量源起爆时间之间的时间。可正可负。
109-110 记录延迟时间――以毫秒表示的能量源起爆时间到数据采样开始记录之间的时间。在SEG Y修订版0中本条用来表示深水作业,如果数据记录不从0时间开始。该条可为负值以适应负的起始时间(即数据记录在零时间之前,假设静校正量应用于数据道的结果)。若某非零值(正或负)记录在该条,它造成的影响的注释应出现在原文文件头。
111-112 起始切除时间(毫秒)
113-114 终止切除时间(毫秒)
115-1167 该道采样点数。强烈推荐所有类型的数据使用
117-1187 该道采样间隔(微秒)。
一道记录的字节数必须和写在道头中的采样点数一致。对所有记录介质都重要,但对正确处理磁盘文件中的SEG Y数据尤为关键(见附录C)。
若二进制文件头中的3503-3504字节设置了固定长度道标志,SEG Y文件每道的采样间隔和采样点数必须与二进制文件头所记录的值一致。若没有设置固定长道标志,采样间隔和采样点数可能每道变化。
强烈推荐所有类型的数据使用
119-120 野外仪器增益类型:
1=固定
2=二进制
3=浮点
4…N=选用
121-122 仪器增益常数(分贝)
123-124 仪器初始增益(分贝)
125-126 相关:
1=无
2=有
127-128 起始扫描频率(赫兹)
129-130 终止扫描频率(赫兹)
131-132 扫描长度(毫秒)
133-134 扫描类型:
1=线性
2=抛物线
3=指数
4=其他
135-136 扫描道斜坡起始长度(毫秒)
137-138 扫描道斜坡终止长度(毫秒)
139-140 斜坡类型:
1=线性
2=cos2
3=其他
141-142 假频滤波频率(赫兹),若使用
143-144 假频滤波坡度(分贝/倍频程)
145-146 陷波频率(赫兹),若使用
147-148 陷波坡度(分贝/倍频程)
149-150 低截频率(赫兹),若使用
151-152 高截频率(赫兹),若使用
153-154 低截坡度(分贝/倍频程)
155-156 高截坡度(分贝/倍频程)
157-158 数据记录的年――1975年标准没有说清应该记成2位还是4位还是两者都用。除SGE Y修订版0外,年份需记录成完整的4位罗马历法年(即2001年应记录为200110(7D116))。
159-160 日(以格林尼治标准时间和通用协调时间为基准的公元日)
161-162 时(24小时制)
163-164 分
165-166 秒
167-168 时间基准码:
1=当地
2=格林尼治标准时间
3=其他,应在扩展原文文件头的用户定义文本段解释
4=通用协调时间
169-170 道加权因子――最小有效位数定义为2-N伏。(N=0,1,…,32767)
171-172 滚动开关位置1的检波器组号
173-174 野外原始记录中道号1的检波器组号
175-176 野外原始记录中最后一道的检波器组号
177-178 间隔大小(滚动时甩掉的总检波器组数)
179-180 相对测线斜坡起始或终止点的移动
1=下(或后)
2=上(或前)
181-184 该道的道集(CDP)位置X坐标(应用道头71-72字节的因子)。参考坐标系应通过扩展头位置数据文本段识别(见D-1节)
185-188 该道的道集(CDP)位置Y坐标(应用道头71-72字节的因子)。参考坐标系应通过扩展头位置数据文本段识别(见D-1节)
189-192 对于3-D叠后数据,本字段用来填纵向线号(In-line)。若每个SEG Y文件记录一条纵向线,文件中所有道的该值应相同,并且同样的值将记录在二进制文件头的3205-3206字节中。
193-196 对于3-D叠后数据,本字段用来填横向线号(Cross-line)。它应与道头21-24字节中的道集(CDP)号的值一致,但这并不是实例。
197-200 炮点号――这可能只应用于2-D叠后数据。
注意在此假设炮点号相对于特定道最靠近叠加(CDP)位置震源位置。如果不是这种情况,应在原文文件头中有注释解释炮点实际参考点。
201-202 应用于道头中197-200字节中炮点号的因子,以得到实际数值。若为正,因子用作乘数;若为负,因子用作除数;若为零;炮点号不用于因子作用(即它是一个整数。典型的值是-10,允许炮点号小数点后有一位小数)。
203-204 道值测量单位:
-1=其他(应在数据采样测量单位文本段描述)
0=未知
1=帕斯卡(Pa)
2=伏特(V)
3=毫伏(mV)
4=安培(A)
5=米(m)
6=米每秒(m/s)
7=米每秒二次方(m/s2)
8=牛顿(N)
9=瓦特(W)
205-210 转换常数――该倍数用于将数据道采样转换成转换单位(道头211-212字节指定)。本常数以4字节编码,尾数是两互补整数(205-208字节)和2字节,十的指数幂是两互补整数(209-210字节)(即(205-208字节)×10**(209-210字节))。
211-212 转换单位――经乘以道头205-210字节中的转换常数后的数据道采样测量单位。
-1=其他(应在数据采样测量单位文本段36页描述)
0=未知
1=帕斯卡(Pa)
2=伏特(V)
3=毫伏(mV)
4=安培(A)
5=米(m)
6=米每秒(m/s)
7=米每秒二次方(m/s2)
8=牛顿(N)
9=瓦特(W)
213-214 设备/道标识――与数据道关联的单位号或设备号(即4368对应可控源号4368或20316对应2船3线16枪)。本字段允许道关联横跨独立于道号的道集(道头25-28字节)
215-216 在道头95-114字节给出的作用于时间的因子,以得到真实的毫秒表示的时间值。因子=1,+10,+100,+1000或+10000。若为正,因子用作乘数;若为负,因子用作除数。为零设定因子为一。
217-218 震源类型/方位――定义类型或能量源的方位。垂直项、横向项、纵向项作为正交坐标系的三个轴。坐标系轴的绝对角度方位可在面元网格定义文本段中定义(27页)
-1到-n=其他(应在震源类型/方位文本段38页描述)
0=未知
1=可控震源――垂直方位
2=可控震源――横向方位
3=可控震源――纵向方位
4=冲击源――垂直方位
5=冲击源――横向方位
6=冲击源――纵向方位
7=分布式冲击源――垂直方位
8=分布式冲击源――横向方位
9=分布式冲击源――纵向方位
219-224 相对震源方位的震源能量方向――正方位方向在道头217-218字节定义。能量方向以度数长度编码(即347.8°编码成3478)
225-230 震源测量――描述产生道的震源效应。测量可以简单,定量的测量如使用炸药总重量或气枪压力峰值或可控源振动次数和扫描周期时间。尽管这些简单的测量可接受,但最好使用真实的能量或工作测量单位。
本常数编码成4字节,尾数为两互补整数(225-228字节)和2字节,十的指数幂是两互补整数(209-230字节)(即(225-228字节)×10**(229-230字节))。
231-232 震源测量单位――用于震源测量、道头225-230字节的单位。
-1=其他(应在震源测量单位文本段39页描述)
0=未知
1=焦耳(J)
2=千瓦(kW)
3=帕斯卡(Pa)
4=巴(Bar)
4=巴-米(Bar-m)
5=牛顿(N)
6=千克(kg)
233-240 未赋值――为任选信息预留
* @author dingyi
*
*/
public class SegyTrace {
// 1-4 测线中道顺序号――若一条测线有若干SEG Y文件号数递增。强烈推荐所有类型的数据使用
int trace_sequence_number_within_line;
// 5-8 SEG Y文件中道顺序号――每个文件以道顺序1开始。
int trace_sequence_number_within_reel;
// 9-12 野外原始记录号。强烈推荐所有类型的数据使用
int original_field_record_number;
// 13-16 野外原始记录的道号。强烈推荐所有类型的数据使用
int trace_sequence_number_within_original_field_record;
// 17-20 震源点号――当在相同有效地表位置多于一个记录时使用。
// 建议在道头197-202字节定义新的条目用于炮点号。
int energy_source_point_number;
// 21-24 道集号(即CDP,CMP,CRP等)
int cdp_ensemble_number;
// 25-28 道集的道数――每个道集从道号1开始
int trace_sequence_number_within_cdp_ensemble;
/**
* 29-30 道识别码: -1=其他 0=未知 1=地震数据 2=死道 3=哑道 4=时断 5=井口 6=扫描 7=定时 8=水断 9=近场枪信号
* 10=远场枪信号 11=地震压力传感器 12=多分量地震传感器――垂直分量 13=多分量地震传感器――横向分量 14=多分量地震传感器――纵向分量
* 15=旋转多分量地震传感器――垂直分量 16=旋转多分量地震传感器――切向分量 17=旋转多分量地震传感器――径向分量 18=可控源反应质量
* 19=可控源底盘 20=可控源估计地面力 21=可控源参考 22=时间速度对 23…N=选用,(最大N=32767) 强烈推荐所有类型的数据使用
* *
*/
short trace_identification_code;// 道识别码
// 31-32 产生该道的垂直叠加道数。(1是一道,2是两道求和,…)
short number_of_vertically_summed_traces_yielding_this_trace;
// 33-34 产生该道的水平叠加道数。(1是一道,2是两道求和,…)
short number_of_horizontally_stacked_traced_yielding_this_trace;
/**
* 35-36 数据用途: 1=生产 2=试验*
*/
short data_use;
// 37-40 从震源中心点到检波器组中心的距离(若与炮激发线方向相反取负)
int distance_from_source_point_to_receiver_group;
// 41-44 检波器组高程(所有基准以上高程为正,以下为负)
// 道头中69-70字节的因子应用于这些数值。
//在二进制文件头3255-3256字节指定单位为英尺或米。
//垂直基准应通过位置数据文本段定义(见D-1节)。
int receiver_group_elevation;
// 45-48 震源地表高程
int surface_elevation_at_source;
// 49-52 震源距地表深度(正数)
int source_depth_below_surface;
// 53-56 检波器组基准高程
int datum_elevation_at_receiver_group;
// 57-60 震源基准高程
int datum_elevation_at_source;
// 61-64 震源水深
int water_depth_at_source;
// 65-68 检波器组水深
int water_depth_at_receiver_group;
// 69-70
// 应用于所有在道头41-68字节给定的真实高程和深度的因子。因子=1,+10,+100,或+1000。若为正,因子为乘数;若为负,因子为除数。
short scalar_for_elevations_and_depths;
// 71-72
// 应用于所有在道头73-88字节和181-188字节给定的真实坐标值的因子。因子=1,+10,+100,或+1000。若为正,因子为乘数;若为负,因子为除数。
short scalar_for_coordinates;
/**
* 73-76 震源坐标――X 参考坐标系应通过扩展头位置数据文本段识别(见D-1节)。
* 若坐标单位为弧度秒、小数度或度/分/秒(DMS),X值代表经度,
* Y值代表纬度。
* 正值代表格林威治子午线以东或赤道以北,
* 负值代表南或西。
*/
int x_source_coordinate;
// 77-80 震源坐标――Y
int y_source_coordinate;
// 81-84 检波器组坐标――X
int x_receiver_group_coordinate;
// 85-88 检波器组坐标――Y
int y_receiver_group_coordinate;
/**
* 89-90 坐标单位: 1=长度(米或英尺) 2=弧度秒 3=小数度 4=度,分,秒(DMS) 注意:为编码±DDDMMSS
* 89-90字节等于±DDD*104+MM*102+SS,71-72字节设置为1;为编码±DDDMMSS
* 89-90字节等于±DDD*106+MM*104+SS*102,71-72字节设置为-100。
*/
short coordinate_units;
// 91-92 风化层速度(如二进制文件头3255-3256字节指明的ft/s或m/s)
short weathering_velocity;
// 93-94 风化层下速度(如二进制文件头3255-3256字节指明的ft/s或m/s)
short subweathering_velocity;
// 95-96 震源处井口时间(毫秒) 毫秒表示的时间需应用道头215-216字节指定的因子。
short uphole_time_at_source;
// 97-98 检波器组处井口时间(毫秒)
short uphole_time_at_group;
// 99-100 震源的静校正量(毫秒)
short source_static_correction;
// 101-102 检波器组的校正量(毫秒)
short group_static_correction;
// 103-104 应用的总静校正量(毫秒)(如没有应用静校正量为零)
short total_static_applied;
// 105-106
// 延迟时间A――以毫秒表示的240字节道识别头的结束和时间断点之间的时间。当时间断点出现在头之后,该值为正;当时间断点出现在头之前,该值为负。时间断点是最初脉冲,它由辅助道记录或由其他记录系统指定。
short lag_time_a;
// 107-108 延迟时间B――以毫秒表示的时间断点到能量源起爆时间之间的时间。可正可负。
short lag_time_b;
// 109-110 记录延迟时间――以毫秒表示的能量源起爆时间到数据采样开始记录之间的时间。在SEG
// Y修订版0中本条用来表示深水作业,如果数据记录不从0时间开始。该条可为负值以适应负的起始时间(即数据记录在零时间之前,假设静校正量应用于数据道的结果)。若某非零值(正或负)记录在该条,它造成的影响的注释应出现在原文文件头。
short delay_according_time;
// 111-112 起始切除时间(毫秒)
short brute_time_start;
// 113-114 终止切除时间(毫秒)
short mute_time_end;
// 115-1167 该道采样点数。强烈推荐所有类型的数据使用
short samples_in_this_trace;
// 117-1187 该道采样间隔(微秒)。
// 一道记录的字节数必须和写在道头中的采样点数一致。对所有记录介质都重要,但对正确处理磁盘文件中的SEG Y数据尤为关键(见附录C)。
// 若二进制文件头中的3503-3504字节设置了固定长度道标志,SEG
// Y文件每道的采样间隔和采样点数必须与二进制文件头所记录的值一致。若没有设置固定长道标志,采样间隔和采样点数可能每道变化。
short sample_intervall;
/**
* 119-120 野外仪器增益类型: 1=固定 2=二进制 3=浮点 4…N=选用
*/
short gain_type_instruments;
// 121-122 仪器增益常数(分贝)
short instrument_gain_para;
// 123-124 仪器初始增益(分贝)
short instrument_initial_gain_para;
// 125-126 相关: 1=无 2=有
short has_relation;
// 127-128 起始扫描频率(赫兹)
short freq_start;
// 129-130 终止扫描频率(赫兹)
short freq_end;
// 131-132 扫描长度(毫秒)
short sweep_length;
// 133-134 扫描类型: 1=线性 2=抛物线 3=指数 4=其他
short sweep_type;
// 135-136 扫描道斜坡起始长度(毫秒)
short sweep_start_length;
// 137-138 扫描道斜坡终止长度(毫秒)
short sweep_end_length;
// 139-140 斜坡类型: 1=线性 2=cos2 3=其他
short sweep_gradient_type;
// 141-142 假频滤波频率(赫兹),若使用
short fake_filter_freq;
// _143-144 假频滤波坡度(分贝/倍频程)
short fake_filter_gradient;
// 145-146 陷波频率(赫兹),若使用
short trap_freq;
// 147-148 陷波坡度(分贝/倍频程)
short trap_gradient;
// 149-150 低截频率(赫兹),若使用
short low_freq;
// 151-152 高截频率(赫兹),若使用
short high_freq;
// 153-154 低截坡度(分贝/倍频程)
short low_gradient;
// 155-156 高截坡度(分贝/倍频程)
short hight_gradient;
// 157-158 数据记录的年――1975年标准没有说清应该记成2位还是4位还是两者都用。
// 除SGE Y修订版0外,年份需记录成完整的4位罗马历法年(即2001年应记录为2001(7D116))。
short year;
// 159-160 日(以格林尼治标准时间和通用协调时间为基准的公元日)
short day;
// 161-162 时(24小时制)
short hour;
// 163-164 分
short minute;
// 165-166 秒
short second;
// 167-168 时间基准码:
/**
* 1=当地 2=格林尼治标准时间 3=其他,应在扩展原文文件头的用户定义文本段解释 4=通用协调时间
*/
short datum_time;
// 169-170 道加权因子――最小有效位数定义为2-N伏。(N=0,1,…,32767)
short trace_factor;
// 171-172 滚动开关位置1的检波器组号
short switch_1_receiver_group;
// 173-174 野外原始记录中道号1的检波器组号
short switch_1_filed_receiver_group;
// 175-176 野外原始记录中最后一道的检波器组号
short last_trace_receiver_group;
// 177-178 间隔大小(滚动时甩掉的总检波器组数)
short interval;
// 179-180 相对测线斜坡起始或终止点的移动 1=下(或后) 2=上(或前)
short translate_start_or_end;
/**
* 81-184 该道的道集(CDP)位置X坐标(应用道头71-72字节的因子)。 参考坐标系应通过扩展头位置数据文本段识别(见D-1节)
*/
int cdp_x;
/**
* 185-188 该道的道集(CDP)位置Y坐标(应用道头71-72字节的因子)。 参考坐标系应通过扩展头位置数据文本段识别(见D-1节)
*/
int cdp_y;
/**
* 189-192 对于3-D叠后数据,本字段用来填纵向线号(In-line)。 若每个SEG Y文件记录一条纵向线,文件中所有道的该值应相同,
* 并且同样的值将记录在二进制文件头的3205-3206字节中。
*/
int in_line_num;
/**
* 193-196 对于3-D叠后数据,本字段用来填横向线号(Cross-line)。
* 它应与道头21-24字节中的道集(CDP)号的值一致,但这并不是实例。
*/
int cross_line_num;
/**
* 197-200 炮点号――这可能只应用于2-D叠后数据。
* 注意在此假设炮点号相对于特定道最靠近叠加(CDP)位置震源位置。如果不是这种情况,应在原文文件头中有注释解释炮点实际参考点。
*/
int source_power_num;
/**
* 201-202 应用于道头中197-200字节中炮点号的因子,以得到实际数值。 若为正,因子用作乘数;若为负,因子用作除数;
* 若为零;炮点号不用于因子作用(即它是一个整数。典型的值是-10, 允许炮点号小数点后有一位小数)。
*/
short source_power_factor;
/**
* 203-204 道值测量单位: -1=其他(应在数据采样测量单位文本段描述) 0=未知 1=帕斯卡(Pa) 2=伏特(V) 3=毫伏(mV)
* 4=安培(A) 5=米(m) 6=米每秒(m/s) 7=米每秒二次方(m/s2) 8=牛顿(N) 9=瓦特(W)
*/
short trace_measure_unit;
/**
* 205-210 转换常数――该倍数用于将数据道采样转换成转换单位 (道头211-212字节指定)。
* 本常数以4字节编码,尾数是两互补整数(205-208字节)和2字节, 十的指数幂是两互补整数(209-210字节)
* (即(205-208字节)×10**(209-210字节))。
*/
long trans_const_factor;
/**
* 211-212 转换单位――经乘以道头205-210字节中的转换常数后的 数据道采样测量单位。 -1=其他(应在数据采样测量单位文本段36页描述)
* 0=未知 1=帕斯卡(Pa) 2=伏特(V) 3=毫伏(mV) 4=安培(A) 5=米(m) 6=米每秒(m/s) 7=米每秒二次方(m/s2)
* 8=牛顿(N) 9=瓦特(W)
*/
short trans_unit;
/**
* 213-214 设备/道标识――与数据道关联的单位号或设备号 (即4368对应可控源号4368或20316对应2船3线16枪)。
* 本字段允许道关联横跨独立于道号的道集(道头25-28字节)
*/
short instrument_trace_id;
/**
* 215-216 在道头95-114字节给出的作用于时间的因子, 以得到真实的毫秒表示的时间值。
* 因子=1,+10,+100,+1000或+10000。 若为正,因子用作乘数;若为负,因子用作除数。为零设定因子为一。
*/
short time_factor;
/*
* 217-218
* 震源类型/方位――定义类型或能量源的方位。垂直项、横向项、纵向项作为正交坐标系的三个轴。坐标系轴的绝对角度方位可在面元网格定义文本段中定义
* (27页) -1到-n=其他(应在震源类型/方位文本段38页描述) 0=未知 1=可控震源――垂直方位 2=可控震源――横向方位
* 3=可控震源――纵向方位 4=冲击源――垂直方位 5=冲击源――横向方位 6=冲击源――纵向方位 7=分布式冲击源――垂直方位
* 8=分布式冲击源――横向方位 9=分布式冲击源――纵向方位
*/
short source_type_or_direction;
/**
* 219-224 相对震源方位的震源能量方向―― 正方位方向在道头217-218字节定义。 能量方向以度数长度编码(即347.8°编码成3478)
*/
long source_power_dirction;
/*
* 225-230 震源测量――描述产生道的震源效应。 测量可以简单,定量的测量如使用炸药总重量或气枪压力峰值 或可控源振动次数和扫描周期时间。
* 尽管这些简单的测量可接受,但最好使用真实的能量或工作测量单位。 本常数编码成4字节,尾数为两互补整数(225-228字节)和2字节,
* 十的指数幂是两互补整数(209-230字节)(即(225-228字节)×10**(229-230字节))。
*/
long source_power_measure;
/*
* 231-232 震源测量单位――用于震源测量、道头225-230字节的单位。 -1=其他(应在震源测量单位文本段39页描述) 0=未知
* 1=焦耳(J) 2=千瓦(kW) 3=帕斯卡(Pa) 4=巴(Bar) 4=巴-米(Bar-m) 5=牛顿(N) 6=千克(kg)
*/
short source_power_measure_unit;//
// 233-240 未赋值――为任选信息预留
public SegyTrace(byte[] b) {
int i = 0;
trace_sequence_number_within_line = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 4;
trace_sequence_number_within_reel = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 8;
original_field_record_number = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 12;
trace_sequence_number_within_original_field_record = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 16;
energy_source_point_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 20;
cdp_ensemble_number = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 24;
trace_sequence_number_within_cdp_ensemble = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 28;
trace_identification_code = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 30;
number_of_vertically_summed_traces_yielding_this_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 32;
number_of_horizontally_stacked_traced_yielding_this_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 34;
data_use = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 36;
distance_from_source_point_to_receiver_group = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 40;
receiver_group_elevation = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 44;
surface_elevation_at_source = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 48;
source_depth_below_surface = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 52;
datum_elevation_at_receiver_group = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 56;
datum_elevation_at_source = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 60;
water_depth_at_source = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 64;
water_depth_at_receiver_group = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 68;
scalar_for_elevations_and_depths = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 70;
scalar_for_coordinates = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 72;
x_source_coordinate = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 76;
y_source_coordinate = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 80;
x_receiver_group_coordinate = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 84;
y_receiver_group_coordinate = b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000)
| (b[i] << 24 & 0xff000000);
i = 88;
coordinate_units = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 90;
weathering_velocity = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 92;
subweathering_velocity = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 94;
uphole_time_at_source = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 96;
uphole_time_at_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 98;
source_static_correction = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 100;
group_static_correction = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 102;
total_static_applied = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 104;
lag_time_a = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 106;
lag_time_b = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 108;
delay_according_time = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 110;
brute_time_start = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 112;
mute_time_end = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 114;
samples_in_this_trace = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 116;
sample_intervall = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 118;
gain_type_instruments = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 120;
instrument_gain_para = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 122;
instrument_initial_gain_para = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 124;
has_relation = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 126;
freq_start = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 128;
freq_end = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 130;
sweep_length = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 132;
sweep_type = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 134;
sweep_start_length = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 136;
sweep_end_length = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 138;
sweep_gradient_type = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 140;
fake_filter_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 142;
fake_filter_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 144;
trap_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 146;
trap_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 148;
low_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 150;
high_freq = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 152;
low_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 154;
hight_gradient = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 156;
year = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 158;
day = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 160;
hour = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 162;
minute = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 164;
second = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 166;
datum_time = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 168;
trace_factor = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 170;
switch_1_receiver_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 172;
switch_1_filed_receiver_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 174;
last_trace_receiver_group = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 176;
interval = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 178;
translate_start_or_end = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 180;
cdp_x = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 184;
cdp_y = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 188;
in_line_num = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 192;
cross_line_num = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 196;
source_power_num = b[i + 3] & 0xff | (b[i + 2] << 8 & 0xff00)
| (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000);
i = 200;
source_power_factor = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 202;
trace_measure_unit = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 204;
trans_const_factor = (long) ((b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000)) * Math
.pow(10, b[i + 5] | (b[i + 4] << 8 & 0xff00)));
i = 210;
trans_unit = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 212;
instrument_trace_id = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 214;
time_factor = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 216;
source_type_or_direction = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));
i = 218;
source_power_dirction = b[i + 5] | (b[i + 4] << 8 & 0xff00)
| (b[i + 3] << 16 & 0xff0000) | (b[i + 2] << 24 & 0xff000000)
| (b[i + 1] << 24 & 0xff000000) << 8
| (b[i] << 24 & 0xff000000) << 16;
i = 224;
source_power_measure = (long) ((b[i + 3] & 0xff
| (b[i + 2] << 8 & 0xff00) | (b[i + 1] << 16 & 0xff0000) | (b[i] << 24 & 0xff000000)) * Math
.pow(10, b[i + 5] | (b[i + 4] << 8 & 0xff00)));
i = 230;
source_power_measure_unit = (short) ((b[i + 1] & 0xff | (b[i] << 8 & 0xff00)));//
}
double[] data;// 存储道值
/**
* 按照IBM浮点数的方式读取数据,对应带头中的数据类型1
* @param buf
* @return
* @throws SegyFileFormatException
*/
public double[] readDataInIBMFormat(byte[] buf) throws SegyFileFormatException {
data = new double[samples_in_this_trace];
for (int i = 0; i < samples_in_this_trace; i++) {
// 按照字节位序一致的方式解读
int sign = (buf[4 * i] >> 7) & 0x01;
int exp = buf[4 * i] & 0x7f;
exp = exp - 64;
int frac = ((buf[4 * i + 1] << 16) & 0x00ff0000)
| ((buf[4 * i + 2] << 8) & 0x0000ff00)
| (buf[4 * i + 3] & 0x000000ff) & 0x00ffffff;
if (frac == 0) {
data[i] = 0;
continue;
}
double result = (1 - 2 * sign) * frac * Math.pow(2, 4 * exp - 24);
// 按照字节位序相反的方式解读,事实证明这样解读是不对的。
//
// byte b1=inverseBit(buf[4*i]);
// byte b2=inverseBit(buf[4*i+1]);
// byte b3=inverseBit(buf[4*i+2]);
// byte b4=inverseBit(buf[4*i+3]);
// int sign=(b1>>7 ) & 0x01;
//
// int exp=b1 & 0x7f;
// exp=exp-64;
// int frac=((b2<<16) & 0x00ff0000) |(( b3 <<8) & 0x0000ff00) | (b4
// & 0x000000ff) & 0x00ffffff;
// if(frac==0 ){
// data[i]=0;
// continue;
// }
// double result=(1-2*sign)*frac/Math.pow(2,24)*Math.pow(16, exp);
data[i] = result;
}
return data;
}
// 翻转字节序
private static byte inverseBit(byte b) {
String temp = Integer.toBinaryString(b & 0xff);
if (temp.length() >= 8) {
temp = temp.substring(temp.length() - 8);
} else {
// 前面补零
int len = temp.length();
for (int i = 0; i < 8 - len; i++) {
temp = "0" + temp;
}
}
System.out.println("转换前:" + temp);
// 把它翻转
String s = "";
for (int i = temp.length() - 1; i >= 0; i--) {
s = s + temp.charAt(i);
}
System.out.println("转换后:" + s);
return (byte) Integer.parseInt(s, 2);
}
public static void main(String[] args) {
System.out.println(Integer.toBinaryString(inverseBit((byte) -128)));
}
/**
* 得到震源地表高程
* 计算方法: (值-基准值)再乘或者除 高程因子,参看规范
* @return
*/
public int getSurface_elevation_at_source() {
if(scalar_for_elevations_and_depths>=0){
return (surface_elevation_at_source-datum_elevation_at_source)*scalar_for_elevations_and_depths;
}else
return -(surface_elevation_at_source-datum_elevation_at_source)/scalar_for_elevations_and_depths;
}
/**
* 得到检波器地表高程
* 计算方法: (值-基准值)再乘或者除 高程因子,参看规范
* @return
*/
public int getReceiver_group_elevation() {
if(scalar_for_elevations_and_depths>=0){
return (receiver_group_elevation-datum_elevation_at_receiver_group)*scalar_for_elevations_and_depths;
}else
return -(receiver_group_elevation-datum_elevation_at_receiver_group)/scalar_for_elevations_and_depths;
}
}
/**
* D-1
*
* 表5 位置数据文本段
文本段头和关键字 格式 注释
((SEG: 位置数据版本1.0)) 文本 文本段名称
以下关键字应用于所有参考坐标系(CRS)
CRS类型= 源于列举表:投影、地理、复合 投影=地图网格
地理=纬度、经度和3-DCRS情况下附加的椭圆高度
复合=准三维坐标系,由2D地理或带与重力相关的高度系统的投影CRS
CRS名称= 文本 参考坐标系名称
大地基准名称= 文本 大地基准名称
本初子午线名称= 文本 若不是“格林威治”,强制
注意:多数,但不是所有,参考坐标系用格林威治作本初子午线(PM)
PM格林威治经度= 实数 CRS的本初子午线相对于格林威治子午线的经度,当在格林威治的东边为正。若本初子午线名称=“格林威治”是不需要
PM格林威治经度单位名称= 文本 若本初子午线名称=“格林威治”是不需要
椭圆名称= 文本
椭圆半主轴= 实数
半主轴单位名称= 文本
椭圆扁率倒数= 实数
坐标轴1名称= 文本 道头73-76,81-84和181-184字节的坐标轴(CS)的名称或缩写。例如东,X,E,或经度
CS轴1方位= 文本 轴1的正方向。例如:“东”或“北”
坐标轴2名称= 文本 道头77-80,85-88和185-188字节的坐标轴(CS)的名称或缩写。例如北,Y,N,或纬度
CS轴2方位= 文本 轴2的正方向。例如:“北”或“东”
垂直基准名称= 文本 垂直基准名称。若使用椭圆高度不需要(多数高度和深度是与重力相关的,而不是椭圆)
坐标轴3名称= 文本 道头41-68字节的高程和深度的坐标轴的名称或缩写。例如:重力相关高度,椭圆高度
CS轴3方位= 文本 轴3的正方向。例如:“上”
以下关键字是投影坐标参考系额外需要的,它是当在字节89-90指明坐标单位是长度或当面元网格定义文本段或数据地理范围扩展文本段或覆盖区域文本段包含在扩展文件头中时
投影区名称= 文本
投影方法名称= 文本 例如:“横向墨卡托”,“朗伯正交圆锥投影(1SP)”,“朗伯正交圆锥投影(2SP)”。
数字和参数类型决定于地图投影方法。对于横向墨卡托和朗伯正交圆锥投影(1SP),需要的5个参数是:
• 原始自然纬度
• 原始自然经度
• 原始自然比例因子
• 东偏
• 北偏
地图投影方法为朗伯正交圆锥投影(2SP)需要的6个参数见下面的示例
投影参数1名称= 文本
投影参数1数值= 实数
投影单位1单位名称= 文本
投影参数2名称= 文本
投影参数2数值= 实数
投影单位2单位名称= 文本
投影参数7名称= 文本
投影参数7数值= 实数
投影单位7单位名称= 文本
D-1.2. 位置数据文本段示例
((SEG: 位置数据版本1.0))
CRS类型= 投影
CRS名称= NAD27/德克萨斯南中心
大地基准名称= 北美1927基准
椭圆名称= 克拉克1866
椭圆半主轴= 6378206.4
半主轴单位名称= 米
椭圆扁率倒数= 294.9786982
坐标轴1名称= Y
CS轴1方位= 北
坐标轴2名称= X
CS轴2方位= 东
投影区名称= 得克萨斯CS27南中心区
投影方法名称= 朗伯正交圆锥投影(2SP)
投影参数1名称= 原始纬度偏差
投影参数1数值= 27.5
投影单位1单位名称= DDD.MMSSsss
投影参数2名称= 原始经度偏差
投影参数2数值= -99
投影单位2单位名称= 度
投影参数3名称= 第一标准平行纬度
投影参数3数值= 28.23
投影单位3单位名称= DDD.MMSSsss
投影参数4名称= 第二标准平行纬度
投影参数4数值= 30.17
投影单位4单位名称= DDD.MMSSsss
投影参数5名称= 原始东偏
投影参数5数值= 2000000.0
投影单位5单位名称= US测量步
投影参数6名称= 原始北偏
投影参数6数值= 0.0
投影单位6单位名称= US测量步
*
*
*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment