Commit ada8e8a2 by zhaopanyu

zpy

parent 44d8c1d0
691c4eb4f452f27efbf167e3169cf31075583538 {"key":"make-fetch-happen:request-cache:https://registry.npmmirror.com/npm","integrity":"sha512-rpHTV+Nur/0NI7NsoFcaAF9P/ceWD0PvGrByxGsl/7nYyZqXXKwiFGk6S6GvT+X0OF+MGsvrajf0HbtwdzRB+Q==","time":1761785616012,"size":2155535,"metadata":{"time":1761785615934,"url":"https://registry.npmmirror.com/npm","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/json; charset=utf-8","date":"Thu, 30 Oct 2025 00:52:03 GMT","etag":"W/\"59f3052e335fd9fb3789dd82ddc90321272ff77b\"","vary":"Origin, Accept, Accept-Encoding"},"options":{"compress":true}}}
\ No newline at end of file
import request from '@/utils/request'
// 批量新增标注(文本/线条)
export function addAll(list) {
return request({
url: '/ysqqXmxxSegydz/segydz/addAll',
method: 'post',
data: { list }
})
}
<template>
<div>
<el-tooltip content="设置" placement="bottom" effect="light">
<el-button @click="editProperties" :class="{ 'active': showLineStylePanel }">
<i class="el-icon-setting"></i>
</el-button>
</el-tooltip>
<el-tooltip content="上传文件" placement="bottom" effect="light">
<el-button @click="triggerFileUpload">
<i class="el-icon-upload"></i>
</el-button>
</el-tooltip>
<el-dialog title="设置" :visible.sync="showPropertiesDialog" width="100%">
<el-form ref="form" label-width="130px">
<el-row>
<el-col :span="5">
<el-form-item label="颜色集合">
<el-select v-model="colorMapSelect" placeholder="请选择颜色集合" @change="changeColor">
<el-option v-for="item in listNameColorMaps" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="归一化类型">
<el-select v-model="NormalizationType" @change="changeNor" placeholder="请选择归一化类型">
<el-option v-for="item in NormalizationTypeData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="归一化比例">
<el-slider @change="changeNor" style="width: 180px;" v-model="NormalizationBl" :min="0.1" :max="5"
:step="0.1" show-stops>
</el-slider>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="每英寸道数">
<el-input v-model="mycds" @blur="changeMycds"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="每秒英寸数">
<el-input v-model="msycs" @blur="changeMycds"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="采样插值类型">
<el-select v-model="samplesType" @change="changeInt" placeholder="请选择采样插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="采样插值边缘">
<el-select v-model="samplesEdge" @change="changeInt" placeholder="请选择采样插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="道插值类型">
<el-select v-model="tracesEdge" @change="changeInt" placeholder="请选择道插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="道插值边缘">
<el-select v-model="tracesType" @change="changeInt" placeholder="请选择道插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="绘图类型">
<el-checkbox v-model="Wiggle" @change="changePlotType">Wiggle</el-checkbox>
<el-checkbox v-model="Reversed" @change="changePlotType">Reversed</el-checkbox>
<el-checkbox v-model="PositiveFill" @change="changePlotType">Positive fill</el-checkbox>
<el-checkbox v-model="NegativeFill" @change="changePlotType">Negative fill</el-checkbox>
<el-checkbox v-model="PositiveColorFill" @change="changePlotType">Positive color fill</el-checkbox>
<el-checkbox v-model="NegativeColorFill" @change="changePlotType">Negative color fill</el-checkbox>
<el-checkbox v-model="SimpleDensity" @change="changePlotType">Simple density</el-checkbox>
<el-checkbox v-model="InterpolatedDensity" @change="changePlotType">Interpolated density</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-裁剪因子">
<el-input v-model="ClippingFactor" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="Wiggle-抽取间距">
<el-input v-model="DecimationSpacing" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-密度抽取">
<el-checkbox v-model="densityDecimation" @change="changePlotType">Density decimation(密度抽取)</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Clipping mode(裁剪模式)">
<el-select v-model="ClippingMode" @change="changePlotType" placeholder="请选择裁剪模式">
<el-option v-for="item in ClippingModeData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="TaperFilter(滤波)">
<el-checkbox v-model="TaperFilterEnbled" @change="changePlotType">启用滤波</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f1">
<el-input v-model="f1" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f2">
<el-input v-model="f2" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f3">
<el-input v-model="f3" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f4">
<el-input v-model="f4" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="采样率">
<el-input v-model="sampleRate" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="带通模式">
<el-checkbox v-model="passFlag" @change="changePlotType">带通模式</el-checkbox>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="AGC">
<el-checkbox v-model="AGCEnbled" @change="changePlotType">启用AGC</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="AGC length">
<el-input v-model="AGCLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Desired average">
<el-input v-model="DesiredAverage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction">
<el-select v-model="NoiseReduction" @change="changePlotType" placeholder="请选择降噪">
<el-option v-for="item in NoiseReductionData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction percentage">
<el-input v-model="NoiseReductionPercentage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Start sample">
<el-input v-model="StartSample" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Step">
<el-input v-model="Step" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="4">
<el-form-item label="Units">
<el-select v-model="Units" @change="changePlotType" placeholder="请选择单位">
<el-option v-for="item in UnitsData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Window length">
<el-input v-model="WindowLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="Reverse">
<el-checkbox v-model="ReverseEnbled" @change="changePlotType">启用Reverse</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="inverted">
<el-checkbox v-model="inverted" @change="changePlotType">启用inverted</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="reversed">
<el-checkbox v-model="reversed" @change="changePlotType">启用reversed</el-checkbox>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="showPropertiesDialog = false">取 消</el-button>
<el-button type="primary" @click="showPropertiesDialog = false">确 定</el-button>
</div>
</el-dialog>
<canvas ref="plot" id="canvas" />
<!-- <PropertiesDialog-->
<!-- :show-dialog="showPropertiesDialog"-->
<!-- :node-props="nodeProps"-->
<!-- :ajv="ajv"-->
<!-- :schema="schema"-->
<!-- @close="applyProps"-->
<!-- />-->
</div>
</template>
<script>
import { SeismicPlot } from './App.js';
import PropertiesDialog from './ui/PropertiesDialog.vue';
import { getAjv, setNodeProps, getNodeProps } from './ui/DialogPropertyUtils';
import { getToken } from "@/utils/auth";
import { SegyReader } from '@int/geotoolkit/seismic/data/SegyReader';
import { LocalFile } from '@int/geotoolkit/seismic/data/LocalFile';
import { Reverse } from '@int/geotoolkit/seismic/pipeline/processor/Reverse';
import { AGC } from '@int/geotoolkit/seismic/pipeline/processor/AGC';
import { TaperFilterProcess } from '@int/geotoolkit/seismic/analysis/filters/TaperFilterProcess';
import { NormalizationType } from '@int/geotoolkit/seismic/pipeline/NormalizationType';
import { SeismicPipeline } from '@int/geotoolkit/seismic/pipeline/SeismicPipeline';
import { SeismicColors } from '@int/geotoolkit/seismic/util/SeismicColors';
let seismicPlot = null;
export default {
name: "index",
components: {
PropertiesDialog
},
data() {
return {
showLineStylePanel: false,
showPropertiesDialog: false,
nodeProps: null,
ajv: null,
schema: null,
chartIsActive: false,
tableIsActive: false,
listNameColorMaps: [
"WhiteBlack",
"RedWhiteBlack",
"RedWhiteBlue",
"Saddleback",
"Angles5color",
"BlackRedYellowWhite",
"GreyOrange",
"IntervalVelocity",
"IntervalVelocity16",
"IntervalVelocity32",
"Rainbow",
"RedGreenBlue",
"RedWhiteBlueExtremes",
"RedWhiteBlueHot",
"RedYellowBlue",
"SaddlebackHot",
"Spectrum"
],
colorMapSelect: "",
_colorMap: "",
pipeline: null,
_seismicWidget: null,
NormalizationType: null,
NormalizationBl: 0.1,
NormalizationTypeData: [
{
"label": "None",
"value": 0,
},
{
"label": "Maximum",
"value": 1,
},
{
"label": "TraceMaximum",
"value": 2,
},
{
"label": "Average",
"value": 3,
},
{
"label": "TraceAverage",
"value": 4,
}, {
"label": "RMS",
"value": 5,
}, {
"label": "TraceRMS",
"value": 6,
}, {
"label": "Limits",
"value": 7,
}
],
mycds: null,
msycs: null,
samplesType: null,
samplesEdge: null,
tracesType: null,
tracesEdge: null,
InterpolationType: [
{
"label": "Linear",
"value": 1,
}, {
"label": "Quadratic",
"value": 2,
}, {
"label": "Step",
"value": 3,
}, {
"label": "CenteredStep",
"value": 4,
}, {
"label": "Cubic",
"value": 5,
}, {
"label": "Logarithmic",
"value": 6,
},
],
InterpolationEdge: [
{
"label": "Zero",
"value": 0,
}, {
"label": "Duplicate",
"value": 1,
}
],
Wiggle: false,
Reversed: false,
PositiveFill: false,
NegativeFill: false,
PositiveColorFill: false,
NegativeColorFill: false,
SimpleDensity: false,
InterpolatedDensity: true,
ClippingFactor: 4,
DecimationSpacing: 5,
densityDecimation: false,
ClippingMode: null,
ClippingModeData: [
{
"label": "Connected",
"value": "Connected"
}, {
"label": "Disconnected",
"value": "Disconnected"
},
],
TaperFilterEnbled: false,
f1: 10,
f2: 20,
f3: 60,
f4: 70,
sampleRate: 0,
passFlag: false,
AGCEnbled: false,
AGCLength: 0,
DesiredAverage: 1,
NoiseReductionPercentage: 3,
NoiseReduction: null,
StartSample: 0,
Step: 1,
Units: "",
WindowLength: 250,
UnitsData: [
{
"label": "Sample",
"value": 0
}, {
"label": "Time",
"value": 1
},
],
NoiseReductionData: [
{
"label": "disable",
"value": "disable"
}, {
"label": "enable",
"value": "enable"
}, {
"label": "auto",
"value": "auto"
},
],
ReverseEnbled: false,
inverted: false,
reversed: false,
// 文件上传相关
uploadUrl: process.env.VUE_APP_BASE_API + '/ndy/dz/upload',
uploadHeaders: {
Authorization: "Bearer " + getToken()
},
fileList: []
}
},
mounted() {
// this.init()
},
methods: {
init(fileName) {
//创建
seismicPlot = new SeismicPlot({
'canvas': this.$refs.plot,
'errorCallback': this.onCreateWidgetError,
'fileOpenedCallback': this.onFileOpen
});
this.handleFileSelect(fileName)
// 不再自动加载默认文件,等待用户上传文件
},
handleFileSelect() {
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile3?fileName=" + fileName;
let fileName = 'density.segy';
return fetch(url, {
headers: {
Authorization: "Bearer " + getToken()
}
}).then((response) => {
if (!response.ok) {
throw new Error(`网络请求失败: ${response.status} ${response.statusText}`);
}
return response.blob();
}).then((blob) => {
if (!blob || blob.size === 0) {
throw new Error('获取到的文件数据为空');
}
let fileInput = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });
// seismicPlot.createWidgetFromFile(filesObj)
const file = new LocalFile(fileInput);
this._fileSize = file.fileSize;
const segyReader = new SegyReader(file);
segyReader.loadMetaData((reader) => {
if (reader instanceof Error && this.errorCallback != null) {
this.errorCallback(reader.message);
return;
}
// this.createRemotePipeline(reader)
reader.readDataSetStatistics((reader, statistics) => {
if (reader.getModelLimits().getHeight() === 0 && this.warningCallback != null) {
return this.$message.error("加载失败");
}
// return this.createPipelineFromFile(file.getFileName(), reader, statistics);
this.pipeline = new SeismicPipeline(file.getFileName(), reader, statistics)
seismicPlot.createPipelineFromFile2(this.pipeline, file.getFileName(), reader, statistics);
console.log(this.pipeline)
});
});
})
},
onCreateWidgetError(errorMsg) {
this.$message.error(errorMsg);
},
editProperties() {
// console.log(seismicPlot)
// this.ajv = getAjv({chartNames: seismicPlot.getChartNames()});
// console.log(this.ajv)
// this.schema = this.ajv.getSchema(`/${seismicPlot.getWidget().getClassName()}`).schema;
// console.log(this.schema)
// this.nodeProps = getNodeProps(seismicPlot);
// console.log(this.nodeProps)
this.showPropertiesDialog = true;
},
applyProps(props) {
if (props) {
setNodeProps(seismicPlot, props);
}
this.showPropertiesDialog = false;
},
onFileOpen() {
},
changeColor(val) {
var colorMap = SeismicColors.getDefault().createNamedColorMap(val, 256)
this.pipeline.setColorMap(colorMap);
if (seismicPlot._seismicWidget) {
seismicPlot._seismicWidget.invalidate(); // 使组件重新渲染
seismicPlot._seismicWidget.fitToBounds(); // 调整视图以适应数据
} else {
console.error('Widget不可用,无法更新视图');
}
// 如果plots对象存在redraw方法,使用它来触发重绘
if (seismicPlot.plots && typeof seismicPlot.plots.redraw === 'function') {
seismicPlot.plots.redraw();
}
},
//归一化
changeNor(val) {
if (this.NormalizationType == 7) {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
}
})
} else {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
}
})
}
},
changeMycds() {
seismicPlot.openPipeline(this.pipeline, {
'tracescale': this.mycds,
'samplescale': this.msycs,
'deviceunit': 'in',
'sampleunit': 's',
});
},
changeInt() {
console.log(this.pipeline.getOptions())
this.pipeline.setOptions({
'interpolation': {
'samples': {
"type": this.samplesType,//采样插值类型,
"edge": this.samplesEdge,//采样插值边缘,
},
'traces': {
"type": this.tracesType,//道插值类型
"edge": this.tracesEdge,//道插值边缘
},
}
})
},
changePlotType() {
this.pipeline.setOptions({
'plot': {
'type': {
"Wiggle": this.Wiggle,
"Reversed": this.Reversed,
"PositiveFill": this.PositiveFill,
"NegativeFill": this.NegativeFill,
"PositiveColorFill": this.PositiveColorFill,
"NegativeColorFill": this.NegativeColorFill,
"SimpleDensity": this.SimpleDensity,
"InterpolatedDensity": this.InterpolatedDensity,
},
"clippingFactor": this.ClippingFactor,
"decimationSpacing": this.DecimationSpacing,
"densityDecimation": this.densityDecimation,
},
"clippingmode": this.ClippingMode,
"dataProcessors": {
"TaperFilter": {
"apply": this.TaperFilterEnbled,
"f1": Number(this.f1),
"f2": Number(this.f2),
"f3": Number(this.f3),
"f4": Number(this.f4),
"sampleRate": Number(this.sampleRate),
"passFlag": this.passFlag,
},
"AGC": {
"agcLength": this.AGCLength,
"apply": this.AGCEnbled,
"desiredAverage": this.DesiredAverage,
"noiseReduction": this.NoiseReduction,
"noiseReductionPercentage": this.NoiseReductionPercentage,
"startSample": this.StartSample,
"step": this.Step,
"units": this.Units,
"windowLength": this.WindowLength,
},
"Reverse": {
"apply": this.ReverseEnbled,
"inverted": this.inverted,
"reversed": this.reversed,
}
}
})
console.log(this.pipeline.getOptions())
},
// 文件上传相关方法
triggerFileUpload() {
// 创建隐藏的文件输入元素
const input = document.createElement('input');
input.type = 'file';
input.accept = '.segy,.sgy';
input.style.display = 'none';
input.onchange = (event) => {
const file = event.target.files[0];
if (file) {
this.handleFileUpload(file);
}
};
document.body.appendChild(input);
input.click();
document.body.removeChild(input);
},
handleFileUpload(file) {
// 检查文件类型
const allowedTypes = ['.segy', '.sgy'];
const fileName = file.name.toLowerCase();
const isValidType = allowedTypes.some(type => fileName.endsWith(type));
if (!isValidType) {
this.$message.error('只能上传segy、sgy文件');
return;
}
// 检查文件大小 (例如限制为100MB)
const maxSize = 100 * 1024 * 1024; // 100MB
if (file.size > maxSize) {
this.$message.error('文件大小不能超过100MB');
return;
}
// 创建FormData
const formData = new FormData();
formData.append('file', file);
// 上传文件
this.$message.info('正在上传文件...');
fetch(this.uploadUrl, {
method: 'POST',
headers: this.uploadHeaders,
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error(`上传失败: ${response.status} ${response.statusText}`);
}
return response.json();
})
.then(data => {
this.$message.success('文件上传成功');
console.log('上传成功:', data);
// 这里可以处理上传成功后的逻辑,比如重新加载数据
// this.loadNewFile(data.newFileName);
this.init(data.fileName)
})
.catch(error => {
console.error('上传失败:', error);
this.$message.error('文件上传失败: ' + error.message);
});
},
loadNewFile(fileName) {
// 加载新文件的逻辑
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile3?fileName=" + fileName;
return fetch(url, {
headers: {
Authorization: "Bearer " + getToken()
}
}).then((response) => {
if (!response.ok) {
throw new Error(`网络请求失败: ${response.status} ${response.statusText}`);
}
return response.blob();
}).then((blob) => {
if (!blob || blob.size === 0) {
throw new Error('获取到的文件数据为空');
}
let fileInput = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });
const file = new LocalFile(fileInput);
this._fileSize = file.fileSize;
const segyReader = new SegyReader(file);
segyReader.loadMetaData((reader) => {
if (reader instanceof Error && this.errorCallback != null) {
this.errorCallback(reader.message);
return;
}
reader.readDataSetStatistics((reader, statistics) => {
if (reader.getModelLimits().getHeight() === 0 && this.warningCallback != null) {
return this.$message.error("加载失败");
}
this.pipeline = new SeismicPipeline(fileName, reader, statistics)
seismicPlot.createPipelineFromFile2(this.pipeline, fileName, reader, statistics);
console.log(this.pipeline)
});
});
}).catch(error => {
console.error('加载文件失败:', error);
this.$message.error('加载文件失败: ' + error.message);
});
}
}
}
</script>
<style scoped>
#canvas {
width: 100% !important;
height: calc(85vh - 35px) !important;
margin-top: 20px;
}
</style>
<template>
<div>
<el-tooltip content="设置" placement="bottom" effect="light">
<el-button @click="editProperties" :class="{ 'active': showLineStylePanel }">
<el-button @click="editProperties" :class="{ 'active': showLineStylePanel }">
<i class="el-icon-setting"></i>
</el-button>
</el-tooltip>
<el-tooltip content="上传文件" placement="bottom" effect="light">
<el-button @click="triggerFileUpload">
<i class="el-icon-upload"></i>
</el-button>
</el-tooltip>
<el-dialog title="设置" :visible.sync="showPropertiesDialog" width="100%">
<el-form ref="form" label-width="130px">
<el-form ref="form" label-width="130px">
<el-row>
<el-col :span="5">
<el-col :span="5">
<el-form-item label="颜色集合">
<el-select v-model="colorMapSelect" placeholder="请选择颜色集合" @change="changeColor">
<el-option v-for="item in listNameColorMaps" :label="item" :value="item"></el-option>
......@@ -25,17 +30,13 @@
</el-col>
<el-col :span="5">
<el-form-item label="归一化比例">
<el-slider @change="changeNor" style="width: 180px;"
v-model="NormalizationBl"
:min="0.1"
:max="5"
:step="0.1"
show-stops>
<el-slider @change="changeNor" style="width: 180px;" v-model="NormalizationBl" :min="0.1" :max="5"
:step="0.1" show-stops>
</el-slider>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="每英寸道数" >
<el-form-item label="每英寸道数">
<el-input v-model="mycds" @blur="changeMycds"></el-input>
</el-form-item>
</el-col>
......@@ -43,26 +44,26 @@
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="每秒英寸数" >
<el-form-item label="每秒英寸数">
<el-input v-model="msycs" @blur="changeMycds"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="采样插值类型" >
<el-form-item label="采样插值类型">
<el-select v-model="samplesType" @change="changeInt" placeholder="请选择采样插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="采样插值边缘" >
<el-form-item label="采样插值边缘">
<el-select v-model="samplesEdge" @change="changeInt" placeholder="请选择采样插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="道插值类型" >
<el-form-item label="道插值类型">
<el-select v-model="tracesEdge" @change="changeInt" placeholder="请选择道插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
......@@ -71,14 +72,14 @@
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="道插值边缘" >
<el-form-item label="道插值边缘">
<el-select v-model="tracesType" @change="changeInt" placeholder="请选择道插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="绘图类型" >
<el-form-item label="绘图类型">
<el-checkbox v-model="Wiggle" @change="changePlotType">Wiggle</el-checkbox>
<el-checkbox v-model="Reversed" @change="changePlotType">Reversed</el-checkbox>
<el-checkbox v-model="PositiveFill" @change="changePlotType">Positive fill</el-checkbox>
......@@ -90,24 +91,24 @@
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-裁剪因子" >
<el-form-item label="Wiggle-裁剪因子">
<el-input v-model="ClippingFactor" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="Wiggle-抽取间距" >
<el-form-item label="Wiggle-抽取间距">
<el-input v-model="DecimationSpacing" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-密度抽取" >
<el-form-item label="Wiggle-密度抽取">
<el-checkbox v-model="densityDecimation" @change="changePlotType">Density decimation(密度抽取)</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Clipping mode(裁剪模式)" >
<el-form-item label="Clipping mode(裁剪模式)">
<el-select v-model="ClippingMode" @change="changePlotType" placeholder="请选择裁剪模式">
<el-option v-for="item in ClippingModeData" :label="item.label" :value="item.value"></el-option>
</el-select>
......@@ -116,37 +117,37 @@
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="TaperFilter(滤波)" >
<el-form-item label="TaperFilter(滤波)">
<el-checkbox v-model="TaperFilterEnbled" @change="changePlotType">启用滤波</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f1" >
<el-form-item label="f1">
<el-input v-model="f1" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f2" >
<el-form-item label="f2">
<el-input v-model="f2" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f3" >
<el-form-item label="f3">
<el-input v-model="f3" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f4" >
<el-form-item label="f4">
<el-input v-model="f4" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="采样率" >
<el-form-item label="采样率">
<el-input v-model="sampleRate" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="带通模式" >
<el-form-item label="带通模式">
<el-checkbox v-model="passFlag" @change="changePlotType">带通模式</el-checkbox>
</el-form-item>
</el-col>
......@@ -154,39 +155,39 @@
<el-row>
<el-col :span="3">
<el-form-item label="AGC" >
<el-form-item label="AGC">
<el-checkbox v-model="AGCEnbled" @change="changePlotType">启用AGC</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="AGC length" >
<el-form-item label="AGC length">
<el-input v-model="AGCLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Desired average" >
<el-form-item label="Desired average">
<el-input v-model="DesiredAverage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction" >
<el-form-item label="Noise reduction">
<el-select v-model="NoiseReduction" @change="changePlotType" placeholder="请选择降噪">
<el-option v-for="item in NoiseReductionData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction percentage" >
<el-form-item label="Noise reduction percentage">
<el-input v-model="NoiseReductionPercentage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Start sample" >
<el-form-item label="Start sample">
<el-input v-model="StartSample" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Step" >
<el-form-item label="Step">
<el-input v-model="Step" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
......@@ -194,14 +195,14 @@
</el-row>
<el-row>
<el-col :span="4">
<el-form-item label="Units" >
<el-form-item label="Units">
<el-select v-model="Units" @change="changePlotType" placeholder="请选择单位">
<el-option v-for="item in UnitsData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Window length" >
<el-form-item label="Window length">
<el-input v-model="WindowLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
......@@ -209,17 +210,17 @@
<el-row>
<el-col :span="3">
<el-form-item label="Reverse" >
<el-form-item label="Reverse">
<el-checkbox v-model="ReverseEnbled" @change="changePlotType">启用Reverse</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="inverted" >
<el-form-item label="inverted">
<el-checkbox v-model="inverted" @change="changePlotType">启用inverted</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="reversed" >
<el-form-item label="reversed">
<el-checkbox v-model="reversed" @change="changePlotType">启用reversed</el-checkbox>
</el-form-item>
</el-col>
......@@ -233,32 +234,32 @@
<canvas ref="plot" id="canvas"/>
<canvas ref="plot" id="canvas" />
<!-- <PropertiesDialog-->
<!-- :show-dialog="showPropertiesDialog"-->
<!-- :node-props="nodeProps"-->
<!-- :ajv="ajv"-->
<!-- :schema="schema"-->
<!-- @close="applyProps"-->
<!-- />-->
<!-- <PropertiesDialog-->
<!-- :show-dialog="showPropertiesDialog"-->
<!-- :node-props="nodeProps"-->
<!-- :ajv="ajv"-->
<!-- :schema="schema"-->
<!-- @close="applyProps"-->
<!-- />-->
</div>
</template>
<script>
import {SeismicPlot} from './App.js';
import { SeismicPlot } from './App.js';
import PropertiesDialog from './ui/PropertiesDialog.vue';
import {getAjv, setNodeProps, getNodeProps} from './ui/DialogPropertyUtils';
import {getToken} from "@/utils/auth";
import {SegyReader} from '@int/geotoolkit/seismic/data/SegyReader';
import {LocalFile} from '@int/geotoolkit/seismic/data/LocalFile';
import {Reverse} from '@int/geotoolkit/seismic/pipeline/processor/Reverse';
import {AGC} from '@int/geotoolkit/seismic/pipeline/processor/AGC';
import {TaperFilterProcess} from '@int/geotoolkit/seismic/analysis/filters/TaperFilterProcess';
import {NormalizationType} from '@int/geotoolkit/seismic/pipeline/NormalizationType';
import {SeismicPipeline} from '@int/geotoolkit/seismic/pipeline/SeismicPipeline';
import {SeismicColors} from '@int/geotoolkit/seismic/util/SeismicColors';
import { getAjv, setNodeProps, getNodeProps } from './ui/DialogPropertyUtils';
import { getToken } from "@/utils/auth";
import { SegyReader } from '@int/geotoolkit/seismic/data/SegyReader';
import { LocalFile } from '@int/geotoolkit/seismic/data/LocalFile';
import { Reverse } from '@int/geotoolkit/seismic/pipeline/processor/Reverse';
import { AGC } from '@int/geotoolkit/seismic/pipeline/processor/AGC';
import { TaperFilterProcess } from '@int/geotoolkit/seismic/analysis/filters/TaperFilterProcess';
import { NormalizationType } from '@int/geotoolkit/seismic/pipeline/NormalizationType';
import { SeismicPipeline } from '@int/geotoolkit/seismic/pipeline/SeismicPipeline';
import { SeismicColors } from '@int/geotoolkit/seismic/util/SeismicColors';
let seismicPlot = null;
export default {
......@@ -300,141 +301,147 @@ export default {
_seismicWidget: null,
NormalizationType: null,
NormalizationBl: 0.1,
NormalizationTypeData:[
NormalizationTypeData: [
{
"label":"None",
"value":0,
"label": "None",
"value": 0,
},
{
"label":"Maximum",
"value":1,
"label": "Maximum",
"value": 1,
},
{
"label":"TraceMaximum",
"value":2,
"label": "TraceMaximum",
"value": 2,
},
{
"label":"Average",
"value":3,
"label": "Average",
"value": 3,
},
{
"label":"TraceAverage",
"value":4,
},{
"label":"RMS",
"value":5,
},{
"label":"TraceRMS",
"value":6,
},{
"label":"Limits",
"value":7,
"label": "TraceAverage",
"value": 4,
}, {
"label": "RMS",
"value": 5,
}, {
"label": "TraceRMS",
"value": 6,
}, {
"label": "Limits",
"value": 7,
}
],
mycds:null,
msycs:null,
samplesType:null,
samplesEdge:null,
tracesType:null,
tracesEdge:null,
InterpolationType:[
mycds: null,
msycs: null,
samplesType: null,
samplesEdge: null,
tracesType: null,
tracesEdge: null,
InterpolationType: [
{
"label":"Linear",
"value":1,
},{
"label":"Quadratic",
"value":2,
},{
"label":"Step",
"value":3,
},{
"label":"CenteredStep",
"value":4,
},{
"label":"Cubic",
"value":5,
},{
"label":"Logarithmic",
"value":6,
"label": "Linear",
"value": 1,
}, {
"label": "Quadratic",
"value": 2,
}, {
"label": "Step",
"value": 3,
}, {
"label": "CenteredStep",
"value": 4,
}, {
"label": "Cubic",
"value": 5,
}, {
"label": "Logarithmic",
"value": 6,
},
],
InterpolationEdge:[
InterpolationEdge: [
{
"label":"Zero",
"value":0,
},{
"label":"Duplicate",
"value":1,
"label": "Zero",
"value": 0,
}, {
"label": "Duplicate",
"value": 1,
}
],
Wiggle:false,
Reversed:false,
PositiveFill:false,
NegativeFill:false,
PositiveColorFill:false,
NegativeColorFill:false,
SimpleDensity:false,
InterpolatedDensity:true,
ClippingFactor:4,
DecimationSpacing:5,
densityDecimation:false,
ClippingMode:null,
ClippingModeData:[
Wiggle: false,
Reversed: false,
PositiveFill: false,
NegativeFill: false,
PositiveColorFill: false,
NegativeColorFill: false,
SimpleDensity: false,
InterpolatedDensity: true,
ClippingFactor: 4,
DecimationSpacing: 5,
densityDecimation: false,
ClippingMode: null,
ClippingModeData: [
{
"label":"Connected",
"value":"Connected"
},{
"label":"Disconnected",
"value":"Disconnected"
"label": "Connected",
"value": "Connected"
}, {
"label": "Disconnected",
"value": "Disconnected"
},
],
TaperFilterEnbled:false,
f1:10,
f2:20,
f3:60,
f4:70,
sampleRate:0,
passFlag:false,
AGCEnbled:false,
AGCLength:0,
DesiredAverage:1,
NoiseReductionPercentage:3,
NoiseReduction:null,
StartSample:0,
Step:1,
Units:"",
WindowLength:250,
UnitsData:[
TaperFilterEnbled: false,
f1: 10,
f2: 20,
f3: 60,
f4: 70,
sampleRate: 0,
passFlag: false,
AGCEnbled: false,
AGCLength: 0,
DesiredAverage: 1,
NoiseReductionPercentage: 3,
NoiseReduction: null,
StartSample: 0,
Step: 1,
Units: "",
WindowLength: 250,
UnitsData: [
{
"label":"Sample",
"value":0
"label": "Sample",
"value": 0
}, {
"label":"Time",
"value":1
"label": "Time",
"value": 1
},
],
NoiseReductionData:[
NoiseReductionData: [
{
"label":"disable",
"value":"disable"
"label": "disable",
"value": "disable"
}, {
"label": "enable",
"value": "enable"
}, {
"label":"enable",
"value":"enable"
},{
"label":"auto",
"value":"auto"
"label": "auto",
"value": "auto"
},
],
ReverseEnbled:false,
inverted:false,
reversed:false,
ReverseEnbled: false,
inverted: false,
reversed: false,
// 文件上传相关
uploadUrl: process.env.VUE_APP_BASE_API + '/ndy/dz/upload',
uploadHeaders: {
Authorization: "Bearer " + getToken()
},
fileList: []
}
},
mounted() {
this.init()
// this.init()
},
methods: {
init() {
......@@ -444,11 +451,11 @@ export default {
'errorCallback': this.onCreateWidgetError,
'fileOpenedCallback': this.onFileOpen
});
this.handleFileSelect()
// 不再自动加载默认文件,等待用户上传文件
},
handleFileSelect() {
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile?fileName=density.segy";
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile3?fileName=density.segy";
let fileName = 'density.segy';
return fetch(url, {
headers: {
......@@ -464,7 +471,7 @@ export default {
if (!blob || blob.size === 0) {
throw new Error('获取到的文件数据为空');
}
let fileInput = new File([blob], fileName, {type: blob.type, lastModified: Date.now()});
let fileInput = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });
// seismicPlot.createWidgetFromFile(filesObj)
const file = new LocalFile(fileInput);
this._fileSize = file.fileSize;
......@@ -481,7 +488,7 @@ export default {
}
// return this.createPipelineFromFile(file.getFileName(), reader, statistics);
this.pipeline = new SeismicPipeline(file.getFileName(), reader, statistics)
seismicPlot.createPipelineFromFile2(this.pipeline,file.getFileName(), reader, statistics);
seismicPlot.createPipelineFromFile2(this.pipeline, file.getFileName(), reader, statistics);
console.log(this.pipeline)
});
});
......@@ -513,8 +520,8 @@ export default {
},
changeColor(val){
var colorMap=SeismicColors.getDefault().createNamedColorMap(val, 256)
changeColor(val) {
var colorMap = SeismicColors.getDefault().createNamedColorMap(val, 256)
this.pipeline.setColorMap(colorMap);
if (seismicPlot._seismicWidget) {
seismicPlot._seismicWidget.invalidate(); // 使组件重新渲染
......@@ -528,16 +535,16 @@ export default {
}
},
//归一化
changeNor(val){
if(this.NormalizationType==7){
this.pipeline .setOptions({
changeNor(val) {
if (this.NormalizationType == 7) {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
}
})
}else {
this.pipeline .setOptions({
} else {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
......@@ -546,7 +553,7 @@ export default {
}
},
changeMycds(){
changeMycds() {
seismicPlot.openPipeline(this.pipeline, {
'tracescale': this.mycds,
'samplescale': this.msycs,
......@@ -554,72 +561,180 @@ export default {
'sampleunit': 's',
});
},
changeInt(){
console.log(this.pipeline .getOptions())
this.pipeline .setOptions({
changeInt() {
console.log(this.pipeline.getOptions())
this.pipeline.setOptions({
'interpolation': {
'samples': {
"type":this.samplesType,//采样插值类型,
"edge":this.samplesEdge,//采样插值边缘,
"type": this.samplesType,//采样插值类型,
"edge": this.samplesEdge,//采样插值边缘,
},
'traces': {
"type":this.tracesType,//道插值类型
"edge":this.tracesEdge,//道插值边缘
"type": this.tracesType,//道插值类型
"edge": this.tracesEdge,//道插值边缘
},
}
})
},
changePlotType(){
this.pipeline .setOptions({
changePlotType() {
this.pipeline.setOptions({
'plot': {
'type': {
"Wiggle":this.Wiggle,
"Reversed":this.Reversed,
"PositiveFill":this.PositiveFill,
"NegativeFill":this.NegativeFill,
"PositiveColorFill":this.PositiveColorFill,
"NegativeColorFill":this.NegativeColorFill,
"SimpleDensity":this.SimpleDensity,
"InterpolatedDensity":this.InterpolatedDensity,
"Wiggle": this.Wiggle,
"Reversed": this.Reversed,
"PositiveFill": this.PositiveFill,
"NegativeFill": this.NegativeFill,
"PositiveColorFill": this.PositiveColorFill,
"NegativeColorFill": this.NegativeColorFill,
"SimpleDensity": this.SimpleDensity,
"InterpolatedDensity": this.InterpolatedDensity,
},
"clippingFactor":this.ClippingFactor,
"decimationSpacing":this.DecimationSpacing,
"densityDecimation":this.densityDecimation,
"clippingFactor": this.ClippingFactor,
"decimationSpacing": this.DecimationSpacing,
"densityDecimation": this.densityDecimation,
},
"clippingmode":this.ClippingMode,
"dataProcessors":{
"TaperFilter":{
"apply":this.TaperFilterEnbled,
"f1":Number(this.f1),
"f2":Number(this.f2),
"f3":Number(this.f3),
"f4":Number(this.f4),
"sampleRate":Number(this.sampleRate),
"passFlag":this.passFlag,
"clippingmode": this.ClippingMode,
"dataProcessors": {
"TaperFilter": {
"apply": this.TaperFilterEnbled,
"f1": Number(this.f1),
"f2": Number(this.f2),
"f3": Number(this.f3),
"f4": Number(this.f4),
"sampleRate": Number(this.sampleRate),
"passFlag": this.passFlag,
},
"AGC":{
"agcLength":this.AGCLength,
"apply":this.AGCEnbled,
"desiredAverage":this.DesiredAverage,
"noiseReduction":this.NoiseReduction,
"noiseReductionPercentage":this.NoiseReductionPercentage,
"startSample":this.StartSample,
"step":this.Step,
"units":this.Units,
"windowLength":this.WindowLength,
"AGC": {
"agcLength": this.AGCLength,
"apply": this.AGCEnbled,
"desiredAverage": this.DesiredAverage,
"noiseReduction": this.NoiseReduction,
"noiseReductionPercentage": this.NoiseReductionPercentage,
"startSample": this.StartSample,
"step": this.Step,
"units": this.Units,
"windowLength": this.WindowLength,
},
"Reverse":{
"apply":this.ReverseEnbled,
"inverted":this.inverted,
"reversed":this.reversed,
"Reverse": {
"apply": this.ReverseEnbled,
"inverted": this.inverted,
"reversed": this.reversed,
}
}
})
console.log(this.pipeline .getOptions())
console.log(this.pipeline.getOptions())
},
// 文件上传相关方法
triggerFileUpload() {
// 创建隐藏的文件输入元素
const input = document.createElement('input');
input.type = 'file';
input.accept = '.segy,.sgy';
input.style.display = 'none';
input.onchange = (event) => {
const file = event.target.files[0];
if (file) {
this.handleFileUpload(file);
}
};
document.body.appendChild(input);
input.click();
document.body.removeChild(input);
},
handleFileUpload(file) {
// 检查文件类型
const allowedTypes = ['.segy', '.sgy'];
const fileName = file.name.toLowerCase();
const isValidType = allowedTypes.some(type => fileName.endsWith(type));
if (!isValidType) {
this.$message.error('只能上传segy、sgy文件');
return;
}
// 检查文件大小 (例如限制为100MB)
const maxSize = 100 * 1024 * 1024; // 100MB
if (file.size > maxSize) {
this.$message.error('文件大小不能超过100MB');
return;
}
// 创建FormData
const formData = new FormData();
formData.append('file', file);
// 上传文件
this.$message.info('正在上传文件...');
fetch(this.uploadUrl, {
method: 'POST',
headers: this.uploadHeaders,
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error(`上传失败: ${response.status} ${response.statusText}`);
}
return response.json();
})
.then(data => {
this.$message.success('文件上传成功');
console.log('上传成功:', data);
// 这里可以处理上传成功后的逻辑,比如重新加载数据
this.loadNewFile(data.fileName);
this.init()
})
.catch(error => {
console.error('上传失败:', error);
this.$message.error('文件上传失败: ' + error.message);
});
},
loadNewFile(fileName) {
// 加载新文件的逻辑
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile3?fileName=" + fileName;
return fetch(url, {
headers: {
Authorization: "Bearer " + getToken()
}
}).then((response) => {
if (!response.ok) {
throw new Error(`网络请求失败: ${response.status} ${response.statusText}`);
}
return response.blob();
}).then((blob) => {
if (!blob || blob.size === 0) {
throw new Error('获取到的文件数据为空');
}
let fileInput = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });
const file = new LocalFile(fileInput);
this._fileSize = file.fileSize;
const segyReader = new SegyReader(file);
segyReader.loadMetaData((reader) => {
if (reader instanceof Error && this.errorCallback != null) {
this.errorCallback(reader.message);
return;
}
reader.readDataSetStatistics((reader, statistics) => {
if (reader.getModelLimits().getHeight() === 0 && this.warningCallback != null) {
return this.$message.error("加载失败");
}
this.pipeline = new SeismicPipeline(fileName, reader, statistics)
seismicPlot.createPipelineFromFile2(this.pipeline, fileName, reader, statistics);
console.log(this.pipeline)
});
});
}).catch(error => {
console.error('加载文件失败:', error);
this.$message.error('加载文件失败: ' + error.message);
});
}
}
}
......@@ -631,5 +746,4 @@ export default {
height: calc(85vh - 35px) !important;
margin-top: 20px;
}
</style>
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -10,22 +10,22 @@
</div>
<!-- 右侧按钮组(与左侧同一行,靠右对齐) -->
<div class="toolbar-right">
<!-- <div class="color-maps">-->
<!-- <el-select v-model="currentColorMap" @change="switchColorMap" size="small">-->
<!-- <el-option v-for="map in colorMaps" :key="map.value" :label="map.label" :value="map.value">-->
<!-- <span class="color-map-option">-->
<!-- <span class="color-map-preview" :class="map.value"></span>-->
<!-- {{ map.label }}-->
<!-- </span>-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<!-- <div class="color-maps">-->
<!-- <el-select v-model="currentColorMap" @change="switchColorMap" size="small">-->
<!-- <el-option v-for="map in colorMaps" :key="map.value" :label="map.label" :value="map.value">-->
<!-- <span class="color-map-option">-->
<!-- <span class="color-map-preview" :class="map.value"></span>-->
<!-- {{ map.label }}-->
<!-- </span>-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </div>-->
<toolbar-controls :plots="plots" :data-loaded="isWidgetReady" :show-line-style-panel="showLineStylePanel"
@toggleLineStylePanel="toggleLineStylePanel" @exporting="exporting = $event"
@closePrintDialog="showPrintDialog = false" />
<el-tooltip content="设置" placement="bottom" effect="light">
<el-button @click="editProperties" :class="{ 'active': showLineStylePanel }">
<el-button @click="editProperties" :class="{ 'active': showLineStylePanel }">
<i class="el-icon-setting"></i>
</el-button>
</el-tooltip>
......@@ -40,6 +40,11 @@
<i class="el-icon-edit"></i>
</el-button>
</el-tooltip>
<el-tooltip content="保存标注" placement="bottom" effect="light">
<el-button type="primary" @click="submitSegyAnnotations">
<i class="el-icon-check"></i>
</el-button>
</el-tooltip>
<!-- <el-tooltip :content="internalScrollbarSyncEnabled ? '内部滚动条同步已启用' : '内部滚动条同步已禁用'" placement="bottom"
effect="light">
<el-button @click="toggleInternalScrollbarSync" :class="{ 'active': internalScrollbarSyncEnabled }">
......@@ -48,13 +53,8 @@
</el-tooltip> -->
</div>
<!-- 缩略图 start-->
<div
v-if="shouldShowThumb"
ref="thumbContainer"
@click="handleThumbClick"
@mousedown="startDrag"
class="right-thumb draggable-thumb"
:style="thumbPosition">
<div v-if="shouldShowThumb" ref="thumbContainer" @click="handleThumbClick" @mousedown="startDrag"
class="right-thumb draggable-thumb" :style="thumbPosition">
<!-- <div class="thumb-title">缩略图</div> -->
<div ref="thumbHolder" class="thumb-holder">
<YsgcIndex v-if="thumbReady" :key="'thumb-' + routeId + '-' + thumbReady" :compact="true" :width="260"
......@@ -67,16 +67,8 @@
</div>
<!-- 缩略图 end-->
<!-- 缩略图弹窗 start -->
<el-dialog
v-if="shouldShowThumb"
title="缩略图预览"
:visible.sync="showThumbDialog"
width="80%"
append-to-body
:z-index="9999999"
:modal="true"
:close-on-click-modal="true"
:close-on-press-escape="true"
<el-dialog v-if="shouldShowThumb" title="缩略图预览" :visible.sync="showThumbDialog" width="80%" append-to-body
:z-index="9999999" :modal="true" :close-on-click-modal="true" :close-on-press-escape="true"
custom-class="thumbnail-dialog">
<div style="height: 100%;">
<YsgcIndex :key="'dialog-thumb-' + routeId" :id-override="routeId" @segyLinePick="onThumbLinePick" />
......@@ -265,12 +257,12 @@
</div>
<!-- 图形设置-->
<!-- 图形设置-->
<el-dialog title="设置" :visible.sync="showPropertiesDialog" width="100%">
<el-form ref="form" label-width="130px">
<el-form ref="form" label-width="130px">
<el-row>
<el-col :span="5">
<el-col :span="5">
<el-form-item label="颜色集合">
<el-select v-model="colorMapSelect" placeholder="请选择颜色集合" @change="changeColor">
<el-option v-for="item in listNameColorMaps" :label="item" :value="item"></el-option>
......@@ -286,44 +278,40 @@
</el-col>
<el-col :span="5">
<el-form-item label="归一化比例">
<el-slider @change="changeNor" style="width: 180px;"
v-model="NormalizationBl"
:min="0.1"
:max="5"
:step="0.1"
show-stops>
<el-slider @change="changeNor" style="width: 180px;" v-model="NormalizationBl" :min="0.1" :max="5"
:step="0.1" show-stops>
</el-slider>
</el-form-item>
</el-col>
<!-- <el-col :span="5">-->
<!-- <el-form-item label="每英寸道数" >-->
<!-- <el-input v-model="mycds" @blur="changeMycds"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- <el-col :span="5">-->
<!-- <el-form-item label="每英寸道数" >-->
<!-- <el-input v-model="mycds" @blur="changeMycds"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
</el-row>
<el-row>
<!-- <el-col :span="5">-->
<!-- <el-form-item label="每秒英寸数" >-->
<!-- <el-input v-model="msycs" @blur="changeMycds"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- <el-col :span="5">-->
<!-- <el-form-item label="每秒英寸数" >-->
<!-- <el-input v-model="msycs" @blur="changeMycds"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="5">
<el-form-item label="采样插值类型" >
<el-form-item label="采样插值类型">
<el-select v-model="samplesType" @change="changeInt" placeholder="请选择采样插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="采样插值边缘" >
<el-form-item label="采样插值边缘">
<el-select v-model="samplesEdge" @change="changeInt" placeholder="请选择采样插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="道插值类型" >
<el-form-item label="道插值类型">
<el-select v-model="tracesEdge" @change="changeInt" placeholder="请选择道插值类型">
<el-option v-for="item in InterpolationType" :label="item.label" :value="item.value"></el-option>
</el-select>
......@@ -332,14 +320,14 @@
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="道插值边缘" >
<el-form-item label="道插值边缘">
<el-select v-model="tracesType" @change="changeInt" placeholder="请选择道插值边缘">
<el-option v-for="item in InterpolationEdge" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="绘图类型" >
<el-form-item label="绘图类型">
<el-checkbox v-model="Wiggle" @change="changePlotType">Wiggle</el-checkbox>
<el-checkbox v-model="Reversed" @change="changePlotType">Reversed</el-checkbox>
<el-checkbox v-model="PositiveFill" @change="changePlotType">Positive fill</el-checkbox>
......@@ -351,24 +339,24 @@
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-裁剪因子" >
<el-form-item label="Wiggle-裁剪因子">
<el-input v-model="ClippingFactor" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="5">
<el-form-item label="Wiggle-抽取间距" >
<el-form-item label="Wiggle-抽取间距">
<el-input v-model="DecimationSpacing" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Wiggle-密度抽取" >
<el-form-item label="Wiggle-密度抽取">
<el-checkbox v-model="densityDecimation" @change="changePlotType">Density decimation(密度抽取)</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="Clipping mode(裁剪模式)" >
<el-form-item label="Clipping mode(裁剪模式)">
<el-select v-model="ClippingMode" @change="changePlotType" placeholder="请选择裁剪模式">
<el-option v-for="item in ClippingModeData" :label="item.label" :value="item.value"></el-option>
</el-select>
......@@ -377,37 +365,37 @@
</el-row>
<el-row>
<el-col :span="3">
<el-form-item label="TaperFilter(滤波)" >
<el-form-item label="TaperFilter(滤波)">
<el-checkbox v-model="TaperFilterEnbled" @change="changePlotType">启用滤波</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f1" >
<el-form-item label="f1">
<el-input v-model="f1" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f2" >
<el-form-item label="f2">
<el-input v-model="f2" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f3" >
<el-form-item label="f3">
<el-input v-model="f3" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="f4" >
<el-form-item label="f4">
<el-input v-model="f4" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="采样率" >
<el-form-item label="采样率">
<el-input v-model="sampleRate" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="带通模式" >
<el-form-item label="带通模式">
<el-checkbox v-model="passFlag" @change="changePlotType">带通模式</el-checkbox>
</el-form-item>
</el-col>
......@@ -415,39 +403,39 @@
<el-row>
<el-col :span="3">
<el-form-item label="AGC" >
<el-form-item label="AGC">
<el-checkbox v-model="AGCEnbled" @change="changePlotType">启用AGC</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="AGC length" >
<el-form-item label="AGC length">
<el-input v-model="AGCLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Desired average" >
<el-form-item label="Desired average">
<el-input v-model="DesiredAverage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction" >
<el-form-item label="Noise reduction">
<el-select v-model="NoiseReduction" @change="changePlotType" placeholder="请选择降噪">
<el-option v-for="item in NoiseReductionData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Noise reduction percentage" >
<el-form-item label="Noise reduction percentage">
<el-input v-model="NoiseReductionPercentage" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Start sample" >
<el-form-item label="Start sample">
<el-input v-model="StartSample" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Step" >
<el-form-item label="Step">
<el-input v-model="Step" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
......@@ -455,14 +443,14 @@
</el-row>
<el-row>
<el-col :span="4">
<el-form-item label="Units" >
<el-form-item label="Units">
<el-select v-model="Units" @change="changePlotType" placeholder="请选择单位">
<el-option v-for="item in UnitsData" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="Window length" >
<el-form-item label="Window length">
<el-input v-model="WindowLength" style="width: 80px" @blur="changePlotType"></el-input>
</el-form-item>
</el-col>
......@@ -470,17 +458,17 @@
<el-row>
<el-col :span="3">
<el-form-item label="Reverse" >
<el-form-item label="Reverse">
<el-checkbox v-model="ReverseEnbled" @change="changePlotType">启用Reverse</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="inverted" >
<el-form-item label="inverted">
<el-checkbox v-model="inverted" @change="changePlotType">启用inverted</el-checkbox>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item label="reversed" >
<el-form-item label="reversed">
<el-checkbox v-model="reversed" @change="changePlotType">启用reversed</el-checkbox>
</el-form-item>
</el-col>
......@@ -532,6 +520,7 @@ import { Reverse } from '@int/geotoolkit/seismic/pipeline/processor/Reverse';
import { Path } from '@int/geotoolkit/scene/shapes/Path';
import * as echarts from 'echarts';
import { toDht } from '@/api/ysqqXmxx/ysqqXmxx';
import { addAll as addAllSegyDz } from '@/api/ysqqXmxxSegydz/segydz'
// 线条样式模式常量
const TEXT_PATTERN_KEYS = Object.keys(TEXT_PATTERNS);
......@@ -583,7 +572,6 @@ const interpolate = function (target, startIndex, endIndex, startColor, endColor
console.error(`interpolate: 创建颜色时出错 - ${error.message}`);
}
};
export default {
name: "YsgcIndex2",
components: {
......@@ -604,6 +592,7 @@ export default {
thumbId: null,
// segy导航相关
segyList: [], // 存储所有segy数据
ysqqXmxxSegy: [], // 保存 toDht 返回的 ysqqXmxxSegy 原始数组
currentSegyIndex: 0, // 当前segy索引
plots: null,
plotsBottom: null,
......@@ -632,6 +621,7 @@ export default {
_headers: [],
_colorMap: null,
savedLineAnnotations: [],
collectedAnnotations: [], // 实时采集缓存
// savedLineAnnotations: [{
// properties: {
// x: [2390.510986101919, 2313.4866975512905, 2307.7161482461947, 2303.4509596293847, 2298.934877564527,
......@@ -964,8 +954,8 @@ export default {
},
// 图形设置
showPropertiesDialog:false,
// 图形设置
showPropertiesDialog: false,
......@@ -994,135 +984,135 @@ export default {
// _seismicWidget: null,
NormalizationType: null,
NormalizationBl: 0.1,
NormalizationTypeData:[
NormalizationTypeData: [
{
"label":"None",
"value":0,
"label": "None",
"value": 0,
},
{
"label":"Maximum",
"value":1,
"label": "Maximum",
"value": 1,
},
{
"label":"TraceMaximum",
"value":2,
"label": "TraceMaximum",
"value": 2,
},
{
"label":"Average",
"value":3,
"label": "Average",
"value": 3,
},
{
"label":"TraceAverage",
"value":4,
},{
"label":"RMS",
"value":5,
},{
"label":"TraceRMS",
"value":6,
},{
"label":"Limits",
"value":7,
"label": "TraceAverage",
"value": 4,
}, {
"label": "RMS",
"value": 5,
}, {
"label": "TraceRMS",
"value": 6,
}, {
"label": "Limits",
"value": 7,
}
],
mycds:null,
msycs:null,
samplesType:null,
samplesEdge:null,
tracesType:null,
tracesEdge:null,
InterpolationType:[
mycds: null,
msycs: null,
samplesType: null,
samplesEdge: null,
tracesType: null,
tracesEdge: null,
InterpolationType: [
{
"label":"Linear",
"value":1,
},{
"label":"Quadratic",
"value":2,
},{
"label":"Step",
"value":3,
},{
"label":"CenteredStep",
"value":4,
},{
"label":"Cubic",
"value":5,
},{
"label":"Logarithmic",
"value":6,
"label": "Linear",
"value": 1,
}, {
"label": "Quadratic",
"value": 2,
}, {
"label": "Step",
"value": 3,
}, {
"label": "CenteredStep",
"value": 4,
}, {
"label": "Cubic",
"value": 5,
}, {
"label": "Logarithmic",
"value": 6,
},
],
InterpolationEdge:[
InterpolationEdge: [
{
"label":"Zero",
"value":0,
},{
"label":"Duplicate",
"value":1,
"label": "Zero",
"value": 0,
}, {
"label": "Duplicate",
"value": 1,
}
],
Wiggle:false,
Reversed:false,
PositiveFill:false,
NegativeFill:false,
PositiveColorFill:false,
NegativeColorFill:false,
SimpleDensity:false,
InterpolatedDensity:true,
ClippingFactor:4,
DecimationSpacing:5,
densityDecimation:false,
ClippingMode:null,
ClippingModeData:[
Wiggle: false,
Reversed: false,
PositiveFill: false,
NegativeFill: false,
PositiveColorFill: false,
NegativeColorFill: false,
SimpleDensity: false,
InterpolatedDensity: true,
ClippingFactor: 4,
DecimationSpacing: 5,
densityDecimation: false,
ClippingMode: null,
ClippingModeData: [
{
"label":"Connected",
"value":"Connected"
},{
"label":"Disconnected",
"value":"Disconnected"
"label": "Connected",
"value": "Connected"
}, {
"label": "Disconnected",
"value": "Disconnected"
},
],
TaperFilterEnbled:false,
f1:10,
f2:20,
f3:60,
f4:70,
sampleRate:0,
passFlag:false,
AGCEnbled:false,
AGCLength:0,
DesiredAverage:1,
NoiseReductionPercentage:3,
NoiseReduction:null,
StartSample:0,
Step:1,
Units:"",
WindowLength:250,
UnitsData:[
TaperFilterEnbled: false,
f1: 10,
f2: 20,
f3: 60,
f4: 70,
sampleRate: 0,
passFlag: false,
AGCEnbled: false,
AGCLength: 0,
DesiredAverage: 1,
NoiseReductionPercentage: 3,
NoiseReduction: null,
StartSample: 0,
Step: 1,
Units: "",
WindowLength: 250,
UnitsData: [
{
"label":"Sample",
"value":0
"label": "Sample",
"value": 0
}, {
"label":"Time",
"value":1
"label": "Time",
"value": 1
},
],
NoiseReductionData:[
NoiseReductionData: [
{
"label":"disable",
"value":"disable"
"label": "disable",
"value": "disable"
}, {
"label": "enable",
"value": "enable"
}, {
"label":"enable",
"value":"enable"
},{
"label":"auto",
"value":"auto"
"label": "auto",
"value": "auto"
},
],
ReverseEnbled:false,
inverted:false,
reversed:false,
ReverseEnbled: false,
inverted: false,
reversed: false,
};
},
computed: {
......@@ -1268,6 +1258,178 @@ export default {
window.removeEventListener('resize', this.updateBaseCanvasSize);
},
methods: {
// 将一个绘制节点序列化为简易对象
serializeNode(node) {
if (!node) return null
const props = typeof node.getProperties === 'function' ? node.getProperties() : {}
if (typeof node.getText === 'function' || typeof props.text === 'string' || node.text) {
const text = typeof node.getText === 'function' ? node.getText() : (node.text || props.text || '')
return { type: 'text', text, properties: props || {} }
}
return { type: 'path', properties: props || {} }
},
// 获取所有需要提交的标注节点(包含图层中的节点和当前工具正在编辑的节点)
getAllAnnotationNodes() {
const nodes = []
try {
const layer = this.annotations
if (layer && typeof layer.getChildren === 'function') {
const children = layer.getChildren() || []
for (const n of children) nodes.push(n)
}
// 同时尝试从上下两个 widget 的 overlay/manipulator 层获取
const tryPushLayerChildren = (widget) => {
if (!widget || typeof widget.getOverlayLayer !== 'function') return
try {
const overlay = widget.getOverlayLayer()
const manip = widget.getManipulatorLayer && widget.getManipulatorLayer()
const arrs = []
if (overlay && typeof overlay.getChildren === 'function') arrs.push(overlay.getChildren() || [])
if (manip && typeof manip.getChildren === 'function') arrs.push(manip.getChildren() || [])
for (const arr of arrs) {
for (const n of arr) {
if (nodes.indexOf(n) === -1) nodes.push(n)
}
}
} catch (e) { }
}
tryPushLayerChildren(this._seismicWidget)
tryPushLayerChildren(this._seismicWidgetBottom)
// 包含当前编辑但可能尚未附加到图层的形状
const toolNodes = []
try { if (this.annotationTool && typeof this.annotationTool.getShape === 'function') { const s = this.annotationTool.getShape(); if (s) toolNodes.push(s) } } catch (e) { }
try { if (this.pencilTool && typeof this.pencilTool.getShape === 'function') { const s = this.pencilTool.getShape(); if (s) toolNodes.push(s) } } catch (e) { }
for (const s of toolNodes) {
if (nodes.indexOf(s) === -1) nodes.push(s)
}
} catch (e) { }
try {
console.log('[collect] nodes total:', nodes.length, 'top/bottom widgets:', !!this._seismicWidget, !!this._seismicWidgetBottom)
nodes.slice(0, 5).forEach((n, i) => {
const hasText = typeof n.getText === 'function'
const props = typeof n.getProperties === 'function' ? n.getProperties() : {}
console.log(`[collect] node#${i}`, hasText ? 'text' : 'path', props)
})
} catch (e) { }
return nodes
},
// 收集当前注释层(文本/线条)为简单可序列化结构
collectAnnotationData() {
const result = []
try {
const nodes = this.getAllAnnotationNodes()
if (!Array.isArray(nodes) || nodes.length === 0) return result
for (const node of nodes) {
const props = typeof node.getProperties === 'function' ? node.getProperties() : {}
// 文本
if (typeof node.getText === 'function') {
const text = node.getText()
const tstyle = typeof node.getTextStyle === 'function' ? node.getTextStyle() : null
result.push({
type: 'text',
text,
properties: props || {},
style: tstyle ? {
font: tstyle.getFont && tstyle.getFont(),
color: tstyle.getColor && tstyle.getColor(),
size: tstyle.size,
alignment: tstyle.getAlignment && tstyle.getAlignment()
} : null
})
} else {
// 线条/路径(Paint工具创建的Path)
result.push({
type: 'path',
properties: props || {}
})
}
}
} catch (e) {
// 忽略
}
try {
console.log('[collect] result length:', result.length, 'sample:', result.slice(0, 2))
} catch (e) { }
return result
},
// 生成批量提交数据并调用后端 addAll 接口
async submitSegyAnnotations() {
try {
// xmid:优先使用路由 id,其次 zbid
const xmid = (this.$route.params && (this.$route.params.id || this.$route.params.zbid))
|| (this.$route.query && (this.$route.query.id || this.$route.query.zbid))
|| null
if (!xmid) {
this.$message.warning('缺少 xmid(路由 id/zbid)')
return
}
// segyid 优先使用 toDht 返回的 ysqqXmxxSegy[0].id,兜底用 segyList[0]
let hasYsqqSegy = Array.isArray(this.ysqqXmxxSegy) && this.ysqqXmxxSegy.length > 0
let hasSegyList = Array.isArray(this.segyList) && this.segyList.length > 0
let seg = hasYsqqSegy ? this.ysqqXmxxSegy[0] : (hasSegyList ? this.segyList[0] : null)
if (!seg || !seg.id) {
console.warn('[submitSegyAnnotations] no seg initially. ysqqXmxxSegy length:', (this.ysqqXmxxSegy || []).length, 'segyList length:', (this.segyList || []).length)
// 尝试重新加载一次数据(页面初进可能尚未完成加载)
try { await this.loadThumbData() } catch (e) { }
hasYsqqSegy = Array.isArray(this.ysqqXmxxSegy) && this.ysqqXmxxSegy.length > 0
hasSegyList = Array.isArray(this.segyList) && this.segyList.length > 0
seg = hasYsqqSegy ? this.ysqqXmxxSegy[0] : (hasSegyList ? this.segyList[0] : null)
console.warn('[submitSegyAnnotations] after reload. ysqqXmxxSegy length:', (this.ysqqXmxxSegy || []).length, 'segyList length:', (this.segyList || []).length)
if (!seg || !seg.id) {
this.$message.warning('未找到对应的 SEGY 信息')
return
}
}
let bznr = this.collectAnnotationData()
// 若仍为空,尝试直接抓取当前工具的 shape
if (!Array.isArray(bznr) || bznr.length === 0) {
try {
const extra = []
const s1 = this.annotationTool && typeof this.annotationTool.getShape === 'function' ? this.annotationTool.getShape() : null
const s2 = this.pencilTool && typeof this.pencilTool.getShape === 'function' ? this.pencilTool.getShape() : null
const n1 = this.serializeNode(s1)
const n2 = this.serializeNode(s2)
if (n1) extra.push(n1)
if (n2) extra.push(n2)
if (extra.length > 0) {
bznr = extra
console.log('[collect] used current tool shapes because layer/cache empty:', extra)
}
} catch (e) { }
}
// 打印准备提交的关键信息
try {
const counts = (Array.isArray(bznr) ? bznr.reduce((acc, it) => { acc[it.type] = (acc[it.type] || 0) + 1; return acc }, {}) : {})
console.log('[submitSegyAnnotations] xmid:', xmid)
console.log('[submitSegyAnnotations] segy candidate from:', hasYsqqSegy ? 'ysqqXmxxSegy[0]' : (hasSegyList ? 'segyList[0]' : 'none'))
console.log('[submitSegyAnnotations] segyid:', seg && seg.id, 'fullSeg:', seg)
console.log('[submitSegyAnnotations] annotations count:', counts, 'total:', Array.isArray(bznr) ? bznr.length : 0)
console.log('[submitSegyAnnotations] annotations sample:', Array.isArray(bznr) ? bznr.slice(0, 2) : bznr)
} catch (e) { }
if (!bznr || bznr.length === 0) {
this.$message.warning('没有可提交的标注数据')
return
}
const list = [{
xmid: xmid,
segyid: seg.id,
lx: '新版',
bznr: JSON.stringify(bznr)
}]
await addAllSegyDz(list)
this.$message.success('标注提交成功')
} catch (e) {
this.$message.error('标注提交失败')
}
},
// 处理路由变化的方法
async handleRouteChange() {
//console.log('[index2] 处理路由变化,重新初始化组件');
......@@ -1486,6 +1648,12 @@ export default {
} catch (error) {
console.error('[index2] 加载segy文件失败:', error);
}
// <-- 自动标注还原
// ysqqXmxxSegy 可能才是原始数据数组
let segList = (Array.isArray(this.ysqqXmxxSegy) && this.ysqqXmxxSegy.length > 0) ? this.ysqqXmxxSegy : this.segyList;
const originSegy = segList[this.currentSegyIndex] || segList[0];
await this.renderAnnotationsFromXbbznr(originSegy);
},
// 清空当前图表
clearCurrentPlots() {
......@@ -2383,6 +2551,7 @@ export default {
}
// 存储完整的segy数据列表
this.segyList = segys;
this.ysqqXmxxSegy = segys; // 同步保留原始数组,供提交时取 [0].id
this.currentSegyIndex = 0; // 重置为第一个
//console.log('[index2] segyList length:', this.segyList.length);
//console.log('[index2] segyList sample:', this.segyList.slice(0, 2));
......@@ -2630,15 +2799,15 @@ export default {
this.baseCanvasHeight = scrollHeight;
//console.log('用户缩放后更新滚动区域尺寸:', {
// containerSize: { width: containerWidth, height: containerHeight },
// currentLimits: {
// width: viewWidth,
// height: viewHeight,
// left: currentLimits.getLeft(),
// right: currentLimits.getRight(),
// top: currentLimits.getTop(),
// bottom: currentLimits.getBottom()
// },
// containerSize: { width: containerWidth, height: containerHeight },
// currentLimits: {
// width: viewWidth,
// height: viewHeight,
// left: currentLimits.getLeft(),
// right: currentLimits.getRight(),
// top: currentLimits.getTop(),
// bottom: currentLimits.getBottom()
// },
// scaleX, scaleY,
// newScrollWidth: scrollWidth,
// newScrollHeight: scrollHeight
......@@ -2666,7 +2835,6 @@ export default {
console.warn('禁用滚动条工具失败:', e);
}
},
// 禁用单个widget的滚动条
disableWidgetScrollbar(widget) {
try {
......@@ -2899,7 +3067,14 @@ export default {
this.pipelineBottom = pipelineBottom;
this._seismicWidgetBottom.setPipeline(pipelineBottom);
this._seismicWidgetBottom.setOptions({ 'axes': { 'headers': { 'fields': this._headers }, 'samples': { 'title': { 'visible': true, 'text': pipelineBottom.getName() } } } });
this._seismicWidgetBottom.setOptions({
'axes': {
'headers': { 'fields': this._headers },
'samples': {
'title': { 'visible': true, 'text': pipelineBottom.getName() }
}
}
});
// 延迟调用fitToBounds,确保初始状态稳定
setTimeout(() => {
this._seismicWidgetBottom.fitToBounds();
......@@ -3451,7 +3626,6 @@ export default {
console.warn('设置DOM滚动条同步失败:', e);
}
},
// 获取外层滚动容器(GeoToolkit 3.2.80兼容)
getOuterScrollContainer(widget) {
try {
......@@ -4556,14 +4730,26 @@ export default {
})
.addListener(EditEvents.End, (tool, node) => {
if (node) {
tool.setEditMode(EditMode.EditNode);
tool.editNode(node);
this.selectedShape = node;
this.saveAnnotation(node);
//console.log('编辑完成:', {
// type: node.getType ? node.getType() : '未知类型',
// properties: node.getProperties()
// });
let text = '';
if (typeof node.getText === 'function') {
text = node.getText();
} else if (node.text) {
text = node.text;
} else if (node.getProperties && node.getProperties().text) {
text = node.getProperties().text;
}
const textStyle = node.getTextStyle ? node.getTextStyle() : null;
console.log('[annotationTool][End] 绘制文本节点', {
node,
text,
properties: node.getProperties && node.getProperties(),
textStyle: textStyle ? {
font: textStyle.getFont && textStyle.getFont(),
color: textStyle.getColor && textStyle.getColor(),
size: textStyle.size,
alignment: textStyle.getAlignment && textStyle.getAlignment()
} : null
});
}
this.requestRepaint();
});
......@@ -4675,10 +4861,10 @@ export default {
const textStyle = node.getTextStyle ? node.getTextStyle() : null;
const previousState = node._previousState || {};
//console.log('文本绘制更新:', {
// previous: {
// properties: previousState.properties || {},
// textStyle: previousState.textStyle || {}
// },
// previous: {
// properties: previousState.properties || {},
// textStyle: previousState.textStyle || {}
// },
// current: {
// properties: node.getProperties(),
// bounds: node.getBounds ? node.getBounds() : null,
......@@ -4716,32 +4902,17 @@ export default {
}
const textStyle = node.getTextStyle ? node.getTextStyle() : null;
//console.log('文本绘制完成:', {
// node: {
// type: node.getType ? node.getType() : 'unknown',
// text: text,
// properties: node.getProperties(),
// bounds: node.getBounds ? node.getBounds() : null
// },
// styles: {
// text: {
// font: textStyle ? textStyle.getFont() : null,
// color: textStyle ? textStyle.getColor() : null,
// size: textStyle ? textStyle.size || this.textStyle.size : this.textStyle.size,
// alignment: textStyle ? textStyle.getAlignment() : null
// },
// line: node.getLineStyle ? node.getLineStyle() : null,
// fill: node.getFillStyle ? node.getFillStyle() : null
// },
// validation: {
// isValid: Boolean(node && node.getText),
// hasRequiredProperties: Boolean(
// node.getProperties().ax !== undefined &&
// node.getProperties().ay !== undefined
// ),
// hasStyles: Boolean(textStyle)
// }
// });
console.log('[annotationTool][End] 绘制文本节点', {
node,
text,
properties: node.getProperties && node.getProperties(),
textStyle: textStyle ? {
font: textStyle.getFont && textStyle.getFont(),
color: textStyle.getColor && textStyle.getColor(),
size: textStyle.size,
alignment: textStyle.getAlignment && textStyle.getAlignment()
} : null
});
}
this.requestRepaint();
});
......@@ -4881,6 +5052,11 @@ export default {
// alignment: this.textStyle.align
// }
// });
try {
const props = typeof node.getProperties === 'function' ? node.getProperties() : {};
this.collectedAnnotations.push({ type: 'text', text, properties: props });
console.log('[collect][text][End] cached count:', this.collectedAnnotations.length, 'last:', this.collectedAnnotations[this.collectedAnnotations.length - 1]);
} catch (e) { }
}
});
}
......@@ -5603,16 +5779,19 @@ export default {
})
.addListener(EditEvents.End, (tool, node) => {
if (node) {
// console.log('线条绘制完成:', {
// properties: node.getProperties(),
// bounds: node.getBounds ? node.getBounds() : null
// });
const props = typeof node.getProperties === 'function' ? node.getProperties() : {};
console.log('[pencilTool][End] 绘制线条节点', {
node,
properties: props
});
try {
this.collectedAnnotations.push({ type: 'path', properties: props });
console.log('[collect][path][End] cached count:', this.collectedAnnotations.length, 'last:', this.collectedAnnotations[this.collectedAnnotations.length - 1]);
} catch (e) { }
}
if (node && this.annotations.indexOfChild(node) === -1) {
this.annotations.addChild(node);
}
tool.setEditMode(EditMode.EditNode);
tool.editNode(node);
this.selectedShape = node;
......@@ -5761,7 +5940,6 @@ export default {
return true;
}
},
/**
* 处理菜单动作
*/
......@@ -6323,12 +6501,12 @@ export default {
this.$message.info('已禁用内部滚动条同步 - 使用外部滚动条控制');
}
},
editProperties(){
this.showPropertiesDialog=true;
editProperties() {
this.showPropertiesDialog = true;
},
changeColor(val){
var colorMap=SeismicColors.getDefault().createNamedColorMap(val, 256)
changeColor(val) {
var colorMap = SeismicColors.getDefault().createNamedColorMap(val, 256)
this.pipeline.setColorMap(colorMap);
console.log(this.plots)
......@@ -6358,16 +6536,16 @@ export default {
},
//归一化
changeNor(val){
if(this.NormalizationType==7){
this.pipeline .setOptions({
changeNor(val) {
if (this.NormalizationType == 7) {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
}
})
}else {
this.pipeline .setOptions({
} else {
this.pipeline.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
......@@ -6376,15 +6554,15 @@ export default {
}
//下方图
if(this.NormalizationType==7){
this.pipelineBottom .setOptions({
if (this.NormalizationType == 7) {
this.pipelineBottom.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
}
})
}else {
this.pipelineBottom .setOptions({
} else {
this.pipelineBottom.setOptions({
'normalization': {
'type': this.NormalizationType,
'scale': this.NormalizationBl
......@@ -6392,7 +6570,7 @@ export default {
})
}
},
changeMycds(){
changeMycds() {
this._seismicWidget.setScaleOptions({
'tracescale': this.mycds,
......@@ -6401,17 +6579,17 @@ export default {
'sampleunit': 's',
});
},
changeInt(){
console.log(this.pipeline .getOptions())
changeInt() {
console.log(this.pipeline.getOptions())
this.pipeline.setOptions({
'interpolation': {
'samples': {
"type":this.samplesType,//采样插值类型,
"edge":this.samplesEdge,//采样插值边缘,
"type": this.samplesType,//采样插值类型,
"edge": this.samplesEdge,//采样插值边缘,
},
'traces': {
"type":this.tracesType,//道插值类型
"edge":this.tracesEdge,//道插值边缘
"type": this.tracesType,//道插值类型
"edge": this.tracesEdge,//道插值边缘
},
}
})
......@@ -6419,106 +6597,106 @@ export default {
this.pipelineBottom.setOptions({
'interpolation': {
'samples': {
"type":this.samplesType,//采样插值类型,
"edge":this.samplesEdge,//采样插值边缘,
"type": this.samplesType,//采样插值类型,
"edge": this.samplesEdge,//采样插值边缘,
},
'traces': {
"type":this.tracesType,//道插值类型
"edge":this.tracesEdge,//道插值边缘
"type": this.tracesType,//道插值类型
"edge": this.tracesEdge,//道插值边缘
},
}
})
},
changePlotType(){
this.pipeline .setOptions({
changePlotType() {
this.pipeline.setOptions({
'plot': {
'type': {
"Wiggle":this.Wiggle,
"Reversed":this.Reversed,
"PositiveFill":this.PositiveFill,
"NegativeFill":this.NegativeFill,
"PositiveColorFill":this.PositiveColorFill,
"NegativeColorFill":this.NegativeColorFill,
"SimpleDensity":this.SimpleDensity,
"InterpolatedDensity":this.InterpolatedDensity,
"Wiggle": this.Wiggle,
"Reversed": this.Reversed,
"PositiveFill": this.PositiveFill,
"NegativeFill": this.NegativeFill,
"PositiveColorFill": this.PositiveColorFill,
"NegativeColorFill": this.NegativeColorFill,
"SimpleDensity": this.SimpleDensity,
"InterpolatedDensity": this.InterpolatedDensity,
},
"clippingFactor":this.ClippingFactor,
"decimationSpacing":this.DecimationSpacing,
"densityDecimation":this.densityDecimation,
"clippingFactor": this.ClippingFactor,
"decimationSpacing": this.DecimationSpacing,
"densityDecimation": this.densityDecimation,
},
"clippingmode":this.ClippingMode,
"dataProcessors":{
"TaperFilter":{
"apply":this.TaperFilterEnbled,
"f1":Number(this.f1),
"f2":Number(this.f2),
"f3":Number(this.f3),
"f4":Number(this.f4),
"sampleRate":Number(this.sampleRate),
"passFlag":this.passFlag,
"clippingmode": this.ClippingMode,
"dataProcessors": {
"TaperFilter": {
"apply": this.TaperFilterEnbled,
"f1": Number(this.f1),
"f2": Number(this.f2),
"f3": Number(this.f3),
"f4": Number(this.f4),
"sampleRate": Number(this.sampleRate),
"passFlag": this.passFlag,
},
"AGC":{
"agcLength":this.AGCLength,
"apply":this.AGCEnbled,
"desiredAverage":this.DesiredAverage,
"noiseReduction":this.NoiseReduction,
"noiseReductionPercentage":this.NoiseReductionPercentage,
"startSample":this.StartSample,
"step":this.Step,
"units":this.Units,
"windowLength":this.WindowLength,
"AGC": {
"agcLength": this.AGCLength,
"apply": this.AGCEnbled,
"desiredAverage": this.DesiredAverage,
"noiseReduction": this.NoiseReduction,
"noiseReductionPercentage": this.NoiseReductionPercentage,
"startSample": this.StartSample,
"step": this.Step,
"units": this.Units,
"windowLength": this.WindowLength,
},
"Reverse":{
"apply":this.ReverseEnbled,
"inverted":this.inverted,
"reversed":this.reversed,
"Reverse": {
"apply": this.ReverseEnbled,
"inverted": this.inverted,
"reversed": this.reversed,
}
}
})
console.log(this.pipeline .getOptions())
console.log(this.pipeline.getOptions())
//下方图
this.pipelineBottom .setOptions({
this.pipelineBottom.setOptions({
'plot': {
'type': {
"Wiggle":this.Wiggle,
"Reversed":this.Reversed,
"PositiveFill":this.PositiveFill,
"NegativeFill":this.NegativeFill,
"PositiveColorFill":this.PositiveColorFill,
"NegativeColorFill":this.NegativeColorFill,
"SimpleDensity":this.SimpleDensity,
"InterpolatedDensity":this.InterpolatedDensity,
"Wiggle": this.Wiggle,
"Reversed": this.Reversed,
"PositiveFill": this.PositiveFill,
"NegativeFill": this.NegativeFill,
"PositiveColorFill": this.PositiveColorFill,
"NegativeColorFill": this.NegativeColorFill,
"SimpleDensity": this.SimpleDensity,
"InterpolatedDensity": this.InterpolatedDensity,
},
"clippingFactor":this.ClippingFactor,
"decimationSpacing":this.DecimationSpacing,
"densityDecimation":this.densityDecimation,
"clippingFactor": this.ClippingFactor,
"decimationSpacing": this.DecimationSpacing,
"densityDecimation": this.densityDecimation,
},
"clippingmode":this.ClippingMode,
"dataProcessors":{
"TaperFilter":{
"apply":this.TaperFilterEnbled,
"f1":Number(this.f1),
"f2":Number(this.f2),
"f3":Number(this.f3),
"f4":Number(this.f4),
"sampleRate":Number(this.sampleRate),
"passFlag":this.passFlag,
"clippingmode": this.ClippingMode,
"dataProcessors": {
"TaperFilter": {
"apply": this.TaperFilterEnbled,
"f1": Number(this.f1),
"f2": Number(this.f2),
"f3": Number(this.f3),
"f4": Number(this.f4),
"sampleRate": Number(this.sampleRate),
"passFlag": this.passFlag,
},
"AGC":{
"agcLength":this.AGCLength,
"apply":this.AGCEnbled,
"desiredAverage":this.DesiredAverage,
"noiseReduction":this.NoiseReduction,
"noiseReductionPercentage":this.NoiseReductionPercentage,
"startSample":this.StartSample,
"step":this.Step,
"units":this.Units,
"windowLength":this.WindowLength,
"AGC": {
"agcLength": this.AGCLength,
"apply": this.AGCEnbled,
"desiredAverage": this.DesiredAverage,
"noiseReduction": this.NoiseReduction,
"noiseReductionPercentage": this.NoiseReductionPercentage,
"startSample": this.StartSample,
"step": this.Step,
"units": this.Units,
"windowLength": this.WindowLength,
},
"Reverse":{
"apply":this.ReverseEnbled,
"inverted":this.inverted,
"reversed":this.reversed,
"Reverse": {
"apply": this.ReverseEnbled,
"inverted": this.inverted,
"reversed": this.reversed,
}
}
})
......@@ -6707,7 +6885,8 @@ export default {
.draggable-thumb {
cursor: grab;
user-select: none;
transition: none; /* 拖动时禁用过渡动画 */
transition: none;
/* 拖动时禁用过渡动画 */
}
.draggable-thumb:active {
......@@ -7491,7 +7670,7 @@ export default {
.scrollbar-track,
.gt-scrollbar-thumb,
.gt-scrollbar-track,
/* 仅在地震图可滚动区域内隐藏内部滚动条相关“thumb/track”,避免误伤缩略图 */
/* 仅在地震图可滚动区域内隐藏内部滚动条相关"thumb/track",避免误伤缩略图 */
.sync-section [class*="thumb"]:not(.thumb-holder):not(.thumb-title):not(.right-thumb),
.sync-section [class*="track"] {
display: none !important;
......@@ -7612,4 +7791,4 @@ export default {
.containerBlock {
overflow: visible !important;
}
</style>
</style>
\ No newline at end of file
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