Commit f1c1d74e by jiang'yun

修改问题

parent 9a9e60f0
import '@int/geotoolkit/bootstrap/polyfill';
import {mergeObjects, init} from '@int/geotoolkit/base';
import {ManipulatorType} from '@int/geotoolkit/seismic/widgets/SeismicViewWidget';
import {CgmPlusExport} from '@int/geotoolkit/seismic/cgmplus/CgmPlusExport';
import {BinaryStream} from '@int/geotoolkit/util/stream/BinaryStream';
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 {Selection, Events as SelectionEvents} from '@int/geotoolkit/controls/tools/Selection';
import {CrossHair, Events as CrossHairEvents} from '@int/geotoolkit/controls/tools/CrossHair';
import {RubberBand, Events as RubberBandEvents} from '@int/geotoolkit/controls/tools/RubberBand';
import {Alignment as BoxLayoutAlignment} from '@int/geotoolkit/layout/BoxLayout';
import {ColorBarLocation} from '@int/geotoolkit/controls/shapes/ColorBarLocation';
import {SeismicWidget} from '@int/geotoolkit/seismic/widgets/SeismicWidget';
import {Plot} from '@int/geotoolkit/plot/Plot';
import {Magnifier} from './js/magnifier';
import {Range} from '@int/geotoolkit/util/Range';
import {ColorUtil} from '@int/geotoolkit/util/ColorUtil';
import {Group} from '@int/geotoolkit/scene/Group';
import {Paint} from '@int/geotoolkit/controls/tools/Paint';
import {PaintMode} from '@int/geotoolkit/controls/tools/PaintMode';
import {EditEvents} from '@int/geotoolkit/controls/tools/EditEvents';
import {EditMode} from '@int/geotoolkit/controls/tools/EditMode';
import {RenderingSide} from '@int/geotoolkit/seismic/pipeline/RenderingSide';
import {NodeServerDataProvider} from './js/nodeserverdataprovider'; // eslint-disable-line
import {HttpClient} from '@int/geotoolkit/http/HttpClient';
import {RemoteSeismicReader} from '@int/geotoolkit/seismic/data/RemoteSeismicReader';
import './styles/toolbar.css';
import {Toolbar} from '@int/geotoolkit/controls/toolbar/Toolbar';
import {Label} from '@int/geotoolkit/controls/toolbar/Label';
import {AnchorType} from '@int/geotoolkit/util/AnchorType';
import {AutoNumberFormat} from '@int/geotoolkit/util/AutoNumberFormat';
import {RemoteSeismicDataSource} from '@int/geotoolkit/seismic/data/RemoteSeismicDataSource';
import {JSLoader as JSCompression} from '@int/geotoolkit/seismic/data/compression/JSLoader';
import {WasmLoader as WasmCompression} from '@int/geotoolkit/seismic/data/compression/WasmLoader';
import {JSLoader as JSFilters} from '@int/geotoolkit/seismic/analysis/filters/JSLoader';
import {WasmLoader as WasmFilters} from '@int/geotoolkit/seismic/analysis/filters/WasmLoader';
init({
'imports': [
JSCompression,
WasmCompression,
JSFilters,
WasmFilters
]
});
const MODERN_CSS = [
'.TableView { ',
' fillstyle-color: white;',
' header-textstyle-color: white;',
' header-textstyle-alignment: center;',
' header-headerfillstyle: rgba(95, 151, 217, 1);',
' header-gridstyle-color: rgba(95, 151, 217, 1);',
' content-evenfillstyle: null;',
' content-oddfillstyle: null;',
' content-gridstyle-color: transparent;',
' index-evenfillstyle: null;',
' index-oddfillstyle: null;',
' index-gridstyle-color: transparent;',
' index-highlightrowfillstyle: rgba(95, 151, 217, 0.5);',
' index-activerowfillstyle: rgba(95, 151, 217, 0.5);',
' highlightrowfillstyle: rgba(95, 151, 217, 0.5);',
' highlightcolumnfillstyle: rgba(95, 151, 217, 0.5);',
' activerowfillstyle: rgba(95, 151, 217, 0.5);',
'}'
].join('\n');
export class SeismicPlot {
constructor (options) {
this._magnifier = new Magnifier();
this._canvas = options['canvas'];
this._container = options['container'];
this.warningCallback = options['warningCallback'];
this.rubberBandZoomEndCallback = options['rubberBandZoomEndCallback'];
this.doubleClickCallback = options['doubleClickCallback'];
this.fileOpenedCallback = options['fileOpenedCallback'];
this.errorCallback = options['errorCallback'];
this._seismicWidget = null;
this._annotationOverlay = null;
this._plot = null;
this._fileSize = 0;
this._colorMap = SeismicColors.getDefault().createNamedColorMap('WhiteBlack', 256);
// this._colorMap = SeismicColors.getDefault().createNamedColorMap("RedWhiteBlack", 256);
}
dispose () {
if (this._magnifier) {
this._magnifier.dispose();
}
if (this._plot) {
this._plot.dispose();
}
}
resize () {
if (this._plot != null) {
this._plot.setSize(this._container.clientWidth, this._container.clientHeight);
}
}
createWidgetFromFile (fileInput) {
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.warningCallback();
}
return this.createPipelineFromFile(file.getFileName(), reader, statistics);
});
});
}
createPipelineFromFile (fileName, reader, statistics) {
const pipeline = new SeismicPipeline(fileName, reader, statistics)
.setColorMap(this._colorMap)
.setOptions({
'normalization': {
'type': NormalizationType.RMS,
'scale': 0.4
},
'plot': {
'type': {
'Wiggle': false,
'InterpolatedDensity': true
},
'decimationSpacing': 5
}
})
.addTraceProcessor(new TaperFilterProcess({'apply': false, 'name': 'TaperFilter'}))
.addTraceProcessor(new AGC({'apply': false, 'name': 'AGC'}))
.addTraceProcessor(new Reverse({'apply': false, 'name': 'Reverse'}));
this.openPipeline(pipeline);
this._seismicWidget.setOptions({
'axes': {
'samples': {
'title': {
'visible': true,
'text': pipeline.getName()
}
}
}
});
}
createPipelineFromFile2 (pipeline,fileName, reader, statistics) {
pipeline.setColorMap(this._colorMap)
.setOptions({
'normalization': {
'type': NormalizationType.RMS,
'scale': 0.4
},
'plot': {
'type': {
'Wiggle': false,
'InterpolatedDensity': true
},
'decimationSpacing': 5
}
})
.addTraceProcessor(new TaperFilterProcess({'apply': false, 'name': 'TaperFilter'}))
.addTraceProcessor(new AGC({'apply': false, 'name': 'AGC'}))
.addTraceProcessor(new Reverse({'apply': false, 'name': 'Reverse'}));
this.openPipeline(pipeline);
this._seismicWidget.setOptions({
'axes': {
'samples': {
'title': {
'visible': true,
'text': pipeline.getName()
}
}
}
});
}
createRemotePipeline (reader) {
const pipeline = new SeismicPipeline('Seismic', reader, reader.getStatistics())
.setOptions({
'normalization': {
'type': NormalizationType.Limits,
'scale': 0.3,
'limits': new Range(-15000, 15000)
},
'plot': {
'type': {
'Wiggle': false,
'InterpolatedDensity': true
},
'decimationSpacing': 5
},
'colors': {
'colorMap': this._colorMap
}
})
.addTraceProcessor(new TaperFilterProcess({'apply': false, 'name': 'TaperFilter'}))
.addTraceProcessor(new AGC({'apply': true, 'name': 'AGC'}))
.addTraceProcessor(new Reverse({'apply': false, 'name': 'Reverse'}));
this.openPipeline(pipeline, {
'tracescale': 400,
'samplescale': 2,
'deviceunit': 'in',
'sampleunit': 's'
});
}
createSectionQuery (position, key, oppositeKey) {
if (key.key === 'TraceNumber') {
// 2D seismic does not need the query
return {
'workflow': 'HaarWavelets U',
'error': 2,
'agc': true
};
}
const selectKeys = [];
selectKeys[0] = {
'name': key['key'],
'min': position,
'max': position,
'step': key['increment'],
'order': 'asc'
};
selectKeys[1] = {
'name': oppositeKey['key'],
'min': oppositeKey['min'],
'max': oppositeKey['max'],
'step': oppositeKey['increment'],
'order': 'asc'
};
return {
'workflow': 'HaarWavelets U',
'error': 2,
'agc': true,
'keys': selectKeys,
'options': null,
'emptyTracesKey': {
'name': oppositeKey['key'],
'min': oppositeKey['min'],
'max': oppositeKey['max']
}
};
}
createWidgetFromRemoteFile (host, fileName) {
const data = new RemoteSeismicDataSource({
'host': host,
'file': fileName, // 'data/seismic/WG152D0002-00007A508-PSTM_RAW-FULL_STK-248666312.xgy',
'version': 2
});
data.open(
() => {
const keys = data.getKeys();
const key = keys[0]; // INLINE
const oppositeKey = keys[1]; // XLINE
const query = this.createSectionQuery(key['min'], key, oppositeKey);
data.select(query, (reader) => {
this.createRemotePipeline(reader);
});
}, (err) => {
this.warningCallback(err);
}
);
}
openPipeline (pipeline, scaleOptions) {
if (pipeline == null) {
return;
}
this._headers = [];
this._charts = [];
this._pipeline = pipeline;
const reader = this._pipeline.getReader();
const knownHeaders = reader.getTraceHeaderFields();
let cdpHeader = null;
knownHeaders.forEach((field) => {
if (field.getName() === 'CDP') {
cdpHeader = field;
}
this._headers.push({
'visible': field.getName() === 'CDP',
'name': field.getName(),
'color': 'black'
});
this._charts.push({
'visible': field.getName() === 'CDP',
'name': field.getName(),
'linestyle': ColorUtil.getRandomColorRgb(true)
});
});
if (cdpHeader == null && this._headers[0]) {
this._headers[0]['visible'] = true;
this._charts[0]['visible'] = true;
}
if (this._seismicWidget != null) {
this._seismicWidget.setScaleOptions(scaleOptions || {
'tracescale': 48
})
.setPipeline(this._pipeline)
.setOptions({
'axes': {
'headers': {
'fields': this._headers
}
},
'auxiliarychart': {
'charts': this._charts.filter((chart) => chart['visible'])
}
});
this._magnifier.setPipeline(this._pipeline);
return;
}
let sampleStatus, valueStatus, traceStatus;
const autoFormat = new AutoNumberFormat();
this._plot = new Plot({
'canvasElement': this._canvas,
'root': this._seismicWidget = new SeismicWidget(this._pipeline, {
'layouttype': 'inside',
'statusbar': {
'visible': false,
'sections': {
'info': function (widget, x, y, sample) {
if (sampleStatus == null) return null;
let sampleValue = '';
let traceNumber = '';
let depthValue = '';
if (sample) {
traceNumber = autoFormat.format(sample['traceNumber'] + 1);
if (y != null) {
sampleValue = autoFormat.format(Math.round(sample['sampleValue'] * 10000) / 10000);
depthValue = autoFormat.format(Math.round(sample['location']['y'] * 100) / 100.0);
}
} else {
traceNumber = '';
sampleValue = '';
depthValue = '';
}
sampleStatus.setText(' Depth: ' + depthValue);
valueStatus.setText(' Value: ' + sampleValue);
traceStatus.setText(' Trace: ' + traceNumber);
return {
'samples': ' Time: ' + depthValue,
'value': ' Values: ' + sampleValue,
'traces': ' Trace: ' + traceNumber
};
}
}
},
'table': {
'visible': false,
'size': 150,
'options': {
'tools': {
'horizontalscroll': {
'type': 'geotoolkit.controls.tools.scroll.HorizontalScroll'
},
'verticalscroll': {
'type': 'geotoolkit.controls.tools.scroll.VerticalScroll'
}
}
}
},
'colorbar': {
'axis': {
'size': 20,
'autolabelrotation': true,
'tickgenerator': {
'edge': {
'tickvisible': false,
'labelvisible': false
}
}
},
'title': {
'size': 0
},
'colorbox': {
'size': 10
},
'location': ColorBarLocation.West,
'maxheight': '80%',
'alignment': BoxLayoutAlignment.Center
},
'axes': {
'samples': {
'title': {
'visible': false
}
},
'headers': {
'fields': this._headers,
'options': {
'minimumSpan': 100
}
}
},
'auxiliarychart': {
'size': 120,
'visible': false,
'title': {
'text': 'Auxiliary Chart',
'textstyle': {
'font': '16px Roboto',
'color': 'gray'
},
'size': 20
},
'charts': this._charts.filter((chart) => chart['visible'])
},
'tools': {
'colorbar': {
'enabled': true
}
},
'scroll': {
'horizontal': {
'type': 'geotoolkit.controls.tools.scroll.HorizontalScroll'
},
'vertical': {
'type': 'geotoolkit.controls.tools.scroll.VerticalScroll'
}
}
})
});
this._seismicWidget.setScaleOptions(scaleOptions || {
'tracescale': 48
});
const statusBar = new Toolbar({
// custom toolbar styles:
'size': 30,
'fontsize': 15,
'offset': 10,
'border': '1px solid #A8A8A8',
'classname': 'cs_status_bar',
'gap': 0,
// toolbar buttons list:
'buttons': [
sampleStatus = new Label({
'text': 'Depth',
'title': 'Depth value'
}).setSize(70, 20),
'-', // special symbol for gap
traceStatus = new Label({
'padding': 5,
'text': 'Trace',
'title': 'Trace index'
}).setSize(90, 20),
valueStatus = new Label({
'padding': 15,
'text': 'Value',
'title': 'Sample value'
}).setSize(120, 20)
],
// right-top corner vertical toolbar:
'orientation': 'horizontal',
'alignment': AnchorType.RightBottom,
'tools': this._plot.getTool(),
'node': this._seismicWidget.getAnnotation('center')
});
const manipulatorLayer = this._seismicWidget.getManipulatorLayer();
this._magnifier.setPipeline(this._pipeline, manipulatorLayer);
this._seismicWidget.getToolByType(RubberBand)
.addListener(RubberBandEvents.onZoomEnd, this.rubberBandZoomEndCallback);
let timerInterval = null;
this._magnifierCallback = (sender, eventArgs) => {
const position = eventArgs.getPosition();
if (Number.isFinite(position.getX()) && Number.isFinite(position.getY())) {
this.pickFrame(position.getX(), position.getY());
}
};
this._seismicWidget.getToolByType(CrossHair)
.addListener(CrossHairEvents.onPositionChanged, this._magnifierCallback)
.addListener(CrossHairEvents.onPositionChanged, (sender, eventArgs) => {
if (timerInterval != null && isNaN(eventArgs.getPosition().getX()) ) {
clearTimeout(timerInterval);
timerInterval = null;
const plotSceneBounds = this._seismicWidget.getModel().getVisibleDeviceLimits();
if (plotSceneBounds.contains(eventArgs.getPlotPoint()) === false) {
statusBar.setVisible(false);
}
return;
}
statusBar.setVisible(true);
statusBar.getElement().style.transition = 'opacity 0s linear 0s';
statusBar.getElement().style.opacity = 1;
if (timerInterval != null) {
clearTimeout(timerInterval);
timerInterval = null;
}
timerInterval = setTimeout( () => {
clearTimeout(timerInterval);
timerInterval = null;
statusBar.getElement().style.transition = 'opacity 1s linear 1s';
statusBar.getElement().style.opacity = 0;
}, 200);
});
this._seismicWidget.getToolByType(Selection)
.addListener(SelectionEvents.onDoubleClick, this.doubleClickCallback);
this.initAnnotationTools();
this._seismicWidget.setCss(MODERN_CSS);
}
fitToBounds () {
if (this._seismicWidget.getVisibleSeismicModelLimits().getWidth() >= this._seismicWidget.getSeismicModelLimits().getWidth()) {
const visibleModelLimits = this._seismicWidget.getVisibleSeismicModelLimits()
.setWidth(this._seismicWidget.getSeismicModelLimits().getWidth());
this._seismicWidget.setVisibleSeismicModelLimits(visibleModelLimits);
}
}
pickFrame (x, y) {
if (this._magnifier.getVisible() === true) {
this._magnifier.pickFrame(x, y);
}
return this;
}
exportToPDF (settings, visibleLimitsExport) {
if (!this._seismicWidget) return null;
const options = mergeObjects(settings, visibleLimitsExport ? {
'limits': this._seismicWidget.getModel().getVisibleModelLimits()
} : null);
this._annotations.setVisible(options.printAnnotations);
return this._seismicWidget.exportToPdf(options).then(() => {
this._annotations.setVisible(true);
});
}
getFileSize () {
return this._fileSize || 0;
}
exportToCGM (callback) {
if (!this._seismicWidget) return;
this._annotations.setVisible(false);
const cgmStream = new BinaryStream();
const exporter = new CgmPlusExport();
cgmStream.setSaveOptions({'filename': 'seismic_sample.cgm', 'type': 'cgm'});
exporter.exportToCgmStreamAsync(this._seismicWidget, cgmStream, null, null, null, () => {
cgmStream.save();
this._annotations.setVisible(true);
callback();
});
}
zoomIn () {
if (this._seismicWidget != null) {
this._seismicWidget.zoomIn();
this._annotationTool.update();
}
}
zoomOut () {
if (this._seismicWidget != null) {
this._seismicWidget.zoomOut();
this._annotationTool.update();
}
}
fitToWindow () {
if (!this._seismicWidget) return;
this._seismicWidget.fitToBounds();
this._annotationTool.update();
}
setRubberBandZoomEnabled (enabled) {
if (this._seismicWidget == null) {
return;
}
this._seismicWidget.setManipulatorType(enabled ? ManipulatorType.RubberBand : ManipulatorType.Panning);
}
activateMagnifierZoom () {
if (this._seismicWidget != null) {
this._magnifier.setVisible(!this._magnifier.getVisible());
}
}
getAnnotationLayer () {
return this._annotations;
}
getAnnotationTool () {
return this._annotationTool;
}
setAnnotationToolMode (mode, icon) {
if (mode == null) {
this._annotationTool.setEditMode(EditMode.EditNode);
this._annotationTool.editNode(null);
this._annotationTool.setEnabled(false);
} else {
const modes = {
'Draw Polygon': PaintMode.Polygon,
'Draw Polyline': PaintMode.Polyline,
'Draw Arrow': PaintMode.Arrow,
'Draw Callout': PaintMode.Callout,
'Draw Text': PaintMode.Text,
'Draw Pencil': PaintMode.Pencil
};
mode = modes[mode];
this._annotationTool.setEnabled(true);
this._annotationTool.setProperties({
'editmode': EditMode.Create,
'mode': mode
});
this._annotationTool.getShape()
.setProperty('icon', icon);
}
}
removeAnnotationTool () {
if (!this._annotationTool) return;
if (this._annotationTool.isEnabled() && this._annotationTool.getMode() === PaintMode.Edit &&
this._annotationTool.getShape() != null) {
if (Array.isArray(this._annotationTool.getShape())) {
this._annotationTool.getShape().forEach((shape) => shape.dispose());
} else {
this._annotationTool.getShape().dispose();
}
this._annotationTool.editNode(null);
}
}
setAuxilaryChartVisible (value) {
if (this._seismicWidget == null) {
return;
}
this._seismicWidget.setOptions({
'auxiliarychart': {
'visible': value === true
}
});
}
setTraceHeaderTable (value) {
if (this._seismicWidget == null) {
return;
}
this._seismicWidget.setOptions({
'table': {
'visible': value === true
}
});
}
initAnnotationTools () {
this._annotations = new Group();
this._seismicWidget.getOverlayLayer().addChild(this._annotations);
this._seismicWidget.getTool().insert(0, new Selection()
.setNodeFilter((nodes) => nodes.filter((node) => this._annotations.indexOfChild(node) >= 0))
.addListener(SelectionEvents.onPick, (tool, eventArgs) => {
if (!this._annotationTool.isEnabled()) return;
const selection = eventArgs.getSelection(),
length = selection.length;
if (length === 0 && this._annotationTool.getMode() === PaintMode.Edit) {
this._annotationTool.editNode(null);
} else if (length > 0 && selection[length - 1] !== this._annotationTool.getShape()) {
this._annotationTool.setEditMode(EditMode.EditNode);
this._annotationTool.editNode(selection[length - 1]);
eventArgs.stopPropagation(true, true);
}
}));
this._seismicWidget.getTool().insert(0, this._annotationTool = new Paint({
'layer': this._seismicWidget.getManipulatorLayer(),
'node': {
'radius': 10,
'fillstyle': '#c7e1f6',
'linestyle': {
'color': '#0351ad',
'width': 2
}
},
'handles': {
'anchor': {
'fillstyle': '#8be73d',
'linestyle': '#0351ad'
}
}
}).addListener(EditEvents.Start, (tool, command) => {
this._annotations.addChild(command.getNode());
}).addListener(EditEvents.End, (tool, node) => {
tool.setEditMode(EditMode.EditNode);
tool.editNode(node);
})
.editNode(null)
.setEnabled(false));
}
createServerReader (callback, fileName, errorCallback) {
const host = 'http://localhost:3002/';
const data = new RemoteSeismicDataSource({
'host': host,
'file': fileName,
'version': 'node'
});
data.open(
() => {
data.select({}, (reader) => {
callback(reader);
});
},
errorCallback
);
}
switchOnServerRendering (filePath, errorCallback) {
this.createServerReader((reader) => {
const pipeline = new SeismicPipeline('Seismic', reader, reader.getStatistics());
pipeline.setOptions({
'normalization': {
'type': NormalizationType.RMS,
'scale': 0.4
},
'plot': {
'type': {
'Wiggle': false,
'InterpolatedDensity': true
},
'decimationSpacing': 5
},
'colors': {
'colorMap': SeismicColors.getDefault().createNamedColorMap('RedWhiteBlack') // for colorbar
},
'renderingside': RenderingSide.Server
});
this._seismicWidget.setPipeline(pipeline);
this._seismicWidget.setOptions({
'pickingevent': CrossHairEvents.onPointerUp
});
this._magnifier.setPipeline(pipeline, this._seismicWidget.getManipulatorLayer());
this._pipeline = pipeline;
let fileName = filePath.split('/');
fileName = fileName[fileName.length - 1];
this._seismicWidget.setOptions({
'axes': {
'samples': {
'title': {
'visible': true,
'text': fileName
}
}
}
});
}, filePath, errorCallback);
}
switchOffServerRendering () {
this._seismicWidget.setOptions({
'pickingevent': CrossHairEvents.onPositionChanged
});
this._seismicWidget.getPipeline().setRenderingSide(RenderingSide.Client);
}
getInfo () {
const info = {
tabs: [{
tab: 'Info',
text: 'There is no metadata.'
}],
title: 'Information'
};
if (this._seismicWidget) {
const reader = this._seismicWidget.getPipeline().getReader();
const metadata = reader.getMetaData();
if (metadata) {
const ebcdic = metadata.getEBCDICHeader();
if (ebcdic) {
info.tabs = [{
tab: 'EBCDIC header',
text: ebcdic.map((el) => el.replace(/\+/g, ' ')).join('\n')
}];
}
const fileName = reader.getSeismicFileName();
if (fileName) {
info.title = 'Information: ' + fileName.substr(fileName.lastIndexOf('/') + 1);
}
const binary = metadata.getBinaryHeader();
if (binary) {
info.tabs.push({
tab: 'Binary header',
text: binary
});
}
if (reader instanceof RemoteSeismicReader) {
const host = reader.getHost();
if (host) {
info.tabs.push({
tab: 'Data source',
text: host
});
}
}
}
}
return info;
}
static checkServer (callback, errorCallback) {
const url = 'http://localhost:3002/check';
const httpService = HttpClient.getInstance().getHttp();
httpService.get(url).then(callback, errorCallback);
}
getWidget () {
return this._seismicWidget;
}
getChartNames () {
return this._charts ? this._charts.map((chart) => chart.name) : [];
}
}
<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-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,
}
},
mounted() {
this.init()
},
methods: {
init() {
//创建
seismicPlot = new SeismicPlot({
'canvas': this.$refs.plot,
'errorCallback': this.onCreateWidgetError,
'fileOpenedCallback': this.onFileOpen
});
this.handleFileSelect()
},
handleFileSelect() {
let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile?fileName=density.segy";
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){
console.log(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())
},
}
}
</script>
<style scoped>
#canvas {
width: 100% !important;
height: calc(85vh - 35px) !important;
margin-top: 20px;
}
</style>
import {AbstractTool} from '@int/geotoolkit/controls/tools/AbstractTool';
import {Dimension} from '@int/geotoolkit/util/Dimension';
import {Rectangle} from '@int/geotoolkit/scene/shapes/Rectangle';
import {getAbsolutePosition, createCanvasElement} from '@int/geotoolkit/dom';
import '../styles/magnifier.css';
const addEventListener = function (target, eventName, eventHandler) {
AbstractTool.getNativeEventName(eventName).forEach((event) => {
target.addEventListener(event, eventHandler, true);
});
};
const removeEventListener = function (target, eventName, eventHandler) {
AbstractTool.getNativeEventName(eventName).forEach((event) => {
target.removeEventListener(event, eventHandler, true);
});
};
const getClientPosition = function (eventArgs) {
let clientX = 0, clientY = 0;
if (eventArgs.touches != null && eventArgs.touches.length > 0) {
// touch events
clientX = eventArgs.touches[0].screenX;
clientY = eventArgs.touches[0].screenY;
} else {
// click events
clientX = eventArgs.screenX;
clientY = eventArgs.screenY;
}
return {
x: clientX,
y: clientY
};
};
export class Magnifier {
constructor () {
this._visible = false;
this._canvas = null;
this._size = 20;
this._x = 0;
this._y = 0;
this._lastPickTime = 0;
this.initializeUI();
}
initializeUI () {
this._magnifierDialog = document.createElement('div');
this._magnifierDialog.classList.add('magnifier-dialog');
this._magnifierDialog.style.display = 'none';
this._magnifierDialog.style.zIndex = 1003;
document.body.appendChild(this._magnifierDialog);
this._canvas = createCanvasElement(256, 256);
this._canvas.id = 'magnifier-canvas';
this._magnifierDialog.appendChild(this._canvas);
this._onWindowMouseMove = this.onWindowMouseMove.bind(this);
this._onWindowMouseUp = this.onWindowMouseUp.bind(this);
const onMouseDown = (eventArgs) => {
this.start(eventArgs);
};
addEventListener(this._magnifierDialog, 'pointerdown', onMouseDown);
addEventListener(this._canvas, 'pointerdown', onMouseDown);
}
start (eventArgs) {
if (this._position != null) return;
eventArgs.stopPropagation();
eventArgs.cancelBubble = true;
addEventListener(window, 'pointermove', this._onWindowMouseMove);
addEventListener(window, 'pointerup', this._onWindowMouseUp);
this._position = getAbsolutePosition(this._magnifierDialog);
this._mousePosition = getClientPosition(eventArgs);
}
stop () {
removeEventListener(window, 'pointermove', this._onWindowMouseMove);
removeEventListener(window, 'pointerup', this._onWindowMouseUp);
this._position = null;
this._mousePosition = null;
}
onWindowMouseMove (eventArgs) {
if (eventArgs.buttons === 0) { // bug in IE11: pointer up events can't be caught outside iframe
this.onWindowMouseUp();
return;
}
eventArgs.preventDefault();
eventArgs.stopPropagation();
eventArgs.cancelBubble = true;
const mousePosition = getClientPosition(eventArgs);
this._position.x += mousePosition.x - this._mousePosition.x;
this._position.y += mousePosition.y - this._mousePosition.y;
this._magnifierDialog.style.left = this._position.x + 'px';
this._magnifierDialog.style.top = this._position.y + 'px';
this._mousePosition = mousePosition;
}
onWindowMouseUp (eventArgs) {
this.stop();
}
getVisible () {
return this._visible;
}
setVisible (visible) {
if (this._visible === visible) return this;
this._visible = visible;
if (this._visible === true) {
this._magnifierDialog.style.display = '';
} else {
this._magnifierDialog.style.display = 'none';
}
this._magnifierFrame.setVisible(this._visible);
return this;
}
setPipeline (pipeline, manipulatorLayer) {
this._pipeline = pipeline;
if (this._manipulatorLayer != null) return this;
this._manipulatorLayer = manipulatorLayer;
this._magnifierFrame = new Rectangle(0, 0, 0, 0)
.setVisible(false)
.setLineStyle({
'pixelsnapmode': true
})
.setFillStyle('rgba(255,0,0,0.1)');
this._manipulatorLayer.addChild(this._magnifierFrame);
return this;
}
setFrame (x, y, size) {
const visualLayer = this._manipulatorLayer;
if (!(size instanceof Dimension)) {
size = new Dimension(size, size);
}
size = visualLayer.getSceneTransform().inverseTransformDimension(size, size);
this._magnifierFrame.setRect(x - size.width / 2, y - size.height / 2, x + size.width / 2, y + size.height / 2)
.setVisible(true);
}
pickFrame (x, y) {
if (!Number.isFinite(x) || !Number.isFinite(y)) {
this._canvas.getContext('2d').clearRect(0, 0, this._canvas.width, this._canvas.height);
return;
}
const pickTime = Date.now();
this._lastPickTime = pickTime;
this.setFrame(x, y, this._size);
this._pipeline.exportToImage(this._magnifierFrame.getBounds(), this._canvas, null, 0, 0, null,
() => (pickTime === this._lastPickTime));
}
dispose () {
if (this._position != null) {
this.stop();
}
this._magnifierDialog.removeChild(this._canvas);
this._canvas = null;
document.body.removeChild(this._magnifierDialog);
this._magnifierDialog.classList.remove('magnifier-dialog');
this._magnifierDialog = null;
}
}
import {implementsInterface} from '@int/geotoolkit/base';
import {HttpClient} from '@int/geotoolkit/http/HttpClient';
import {HttpCancel} from '@int/geotoolkit/http/HttpCancel';
import {Promise} from '@int/geotoolkit/util/Promise';
import {RemoteReaderDataProvider} from '@int/geotoolkit/seismic/data/RemoteReaderDataProvider';
import {IServerSideRenderingProvider} from '@int/geotoolkit/seismic/data/IServerSideRenderingProvider';
import {RemoteReaderDataProviderRegistry} from '@int/geotoolkit/seismic/data/RemoteReaderDataProviderRegistry';
import {ErrorCodes} from '@int/geotoolkit/http/ErrorCodes';
import {obfuscate} from '@int/geotoolkit/lib';
import {log} from '@int/geotoolkit/base';
export class NodeServerDataProvider extends RemoteReaderDataProvider {
constructor (options) {
super(options);
this.options = options;
this.http = HttpClient.getInstance().getHttp();
this.token = null;
this.fileName = '';
}
createInstance (options) {
return new NodeServerDataProvider(options);
}
open (fileName) {
this.fileName = fileName;
return this.http.get('seismicdata/' + encodeURIComponent(fileName), {
'responseType': 'json',
'baseURL': this.options['host']
}).then((response) => {
if (response['data'] && response['data']['version']) {
return response['data'];
}
return Promise.reject('Server error');
}, () => Promise.reject('Cannot connect to the server! Run node server.js!'));
}
queryTraces (fileName, query) {
const token = new HttpCancel();
return this.http.get('seismicquery/' + encodeURIComponent(fileName), {
'responseType': 'json',
'baseURL': this.options['host'],
'cancel': token
}).then((response) => {
if (response['data'] && response['data']['version']) {
return response['data'];
}
return Promise.reject('Server error');
}, (error) => {
if (token.isCanceled()) {
return Promise.reject(error);
}
return Promise.reject('Cannot connect to the server! Run node server.js!');
});
}
readTraces (fileName, options) {
if (options && !Array.isArray(options['traceIndexes'])) {
options['traceIndexes'] = [];
for (let i = options['from']; i <= options['to']; ++i) {
options['traceIndexes'].push(i);
}
}
return this.http.request({
'url': 'enumeratedtraces',
'baseURL': this.options['host'],
'method': 'POST',
'responseType': 'arraybuffer',
'headers': {
'Content-Type': 'application/json'
},
'data': {
'file': fileName,
'byteOrder': options['byteOrder'],
'query': options['query'],
'data': {
'byteOrder': options['byteOrder'],
'samples': options['samples'] === true,
'headers': options['headers'] === true,
'traceIndexes': options['traceIndexes']
}
},
'transformResponse': (response) => response['data']
});
}
pickSample (x, y, target, callback) {
const self = this;
if (this.token) {
this.token.cancel();
}
this.token = new HttpCancel();
this.http.get('samples', {
'responseType': 'json',
'baseURL': this.options['host'],
'cancel': self.token,
'params': {
'json': JSON.stringify({
x: x,
y: y,
file: this.fileName
})
}
}).then((response) => {
self.token = null;
callback.call(target, response['data']);
}).catch((error) => {
if (this.token && !this.token.isCanceled() && error.code !== ErrorCodes.Aborted) {
log(error);
}
});
}
getTileURLFormatter () {
return (data) => encodeURI(this.options['host'] + 'seismicimage?json=' + JSON.stringify({
'width': data['deviceArea'].getWidth(),
'height': data['deviceArea'].getHeight(),
'options': data['options'],
'limits': {
'starttrace': data['tileRect'].getX(),
'startsample': data['tileRect'].getY(),
'traceend': data['tileRect'].getRight(),
'sampleend': data['tileRect'].getBottom()
},
'file': this.fileName
}));
}
getTileLoader () {
return (data, callback) => {
const token = new HttpCancel();
this.http.get(data['url'], {
'responseType': null,
'cancel': token
}).then((response) => {
if (response['data']) {
callback(null, response['data']);
} else {
callback('Server error');
}
}).catch((error) => {
if (!token.isCanceled() && error['code'] !== ErrorCodes.Aborted) {
callback(error);
}
});
return token;
};
}
}
implementsInterface(NodeServerDataProvider, IServerSideRenderingProvider);
obfuscate(NodeServerDataProvider);
RemoteReaderDataProviderRegistry.getInstance().register('node', new NodeServerDataProvider());
.magnifier-dialog {
position:absolute;
z-index: 100;
left:50px;
top:100px;
width:270px;
height:270px;
background-color: #F9F9F9;
border: 1px solid #ddd;
border-radius:4px;
}
#magnifier-canvas {
position:absolute;
left:5px;
top:5px;
right:5px;
bottom:5px;
background-color: white;
border: 1px solid #ddd;
border-radius:2px;
}
/* Default Toolbar CSS */
/* font-awesome for button icons */
/*@import 'font-awesome.css';*/
/* toolbar container for canvas + all toolbars */
.cg-toolbar-container {
background-color: white;
position: relative;
}
.cg-toolbar-container > canvas {
margin: 0;
}
/* toolbar classes: */
.cg-toolbar-left, .cg-toolbar-top, .cg-toolbar-right, .cg-toolbar-bottom {
display: flex;
pointer-events: none;
}
/* toolbar directions: */
.cg-toolbar-left, .cg-toolbar-right {
flex-direction: column;
}
.cg-toolbar-top, .cg-toolbar-bottom {
flex-direction: row;
}
/* snap items to the right/bottom: */
.cg-toolbar-right, .cg-toolbar-bottom {
align-items: flex-end;
}
/* group of buttons class: */
.cg-toolbar-group {
display: flex;
flex-direction: inherit;
align-items: inherit;
border-radius: inherit;
}
/* gap between groups */
.cg-toolbar-left .cg-toolbar-group + .cg-toolbar-group,
.cg-toolbar-right .cg-toolbar-group + .cg-toolbar-group {
margin-top: 15px;
}
.cg-toolbar-top .cg-toolbar-group + .cg-toolbar-group,
.cg-toolbar-bottom .cg-toolbar-group + .cg-toolbar-group {
margin-left: 15px;
}
/* single button class: */
.cg-toolbar-button {
height: auto;
text-align: center;
cursor: pointer;
color: black;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.3);
pointer-events: all;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* checkbox class: */
.cg-toolbar-checkbox {
white-space: nowrap;
overflow: hidden;
}
/* checkbox inner text class: */
.cg-toolbar-checkbox-text {
display: inline-block;
}
span + .cg-toolbar-checkbox-text {
margin-left: 3px;
}
/* dropdown button class: */
.cg-toolbar-dropdown {
display: flex;
border-radius: inherit;
}
/* dropdown directions: */
.cg-toolbar-left .cg-toolbar-dropdown {
flex-direction: row;
}
.cg-toolbar-top .cg-toolbar-dropdown {
flex-direction: column;
}
.cg-toolbar-right .cg-toolbar-dropdown {
flex-direction: row-reverse;
}
.cg-toolbar-bottom .cg-toolbar-dropdown {
flex-direction: column-reverse;
}
/* first (dropdown) button inherits size from dropdown: */
.cg-toolbar-dropdown > :first-child {
width: inherit;
min-width: inherit;
height: inherit;
min-height: inherit;
line-height: inherit;
}
/* dropdown over the other buttons: */
.cg-toolbar-dropdown > :not(:first-child) {
z-index: 1;
}
/* hide dropdown buttons if not hover: */
.cg-toolbar-dropdown:not(:hover):not(.cg-toolbar-checked) > :not(:first-child) {
display: none;
}
/* checked style for checkboxes (doesn't affect dropdowns): */
.cg-toolbar-checked:not(.cg-toolbar-dropdown) {
background-color: rgb(0, 195, 0) !important;
color: white;
}
/* buttons highlight on hover: */
.cg-toolbar-button.cg-toolbar-checked:hover > :not(.cg-toolbar-button),
.cg-toolbar-button:not(.cg-toolbar-checked):not(:hover) > :not(.cg-toolbar-button) {
opacity: 0.7;
}
/* gap between buttons: */
.cg-toolbar-gap {
pointer-events: none;
cursor: pointer;
}
.cg-toolbar-top .cg-toolbar-dropdown > .cg-toolbar-gap, .cg-toolbar-bottom .cg-toolbar-dropdown > .cg-toolbar-gap {
pointer-events: all;
width: 100% !important;
}
.cg-toolbar-left .cg-toolbar-dropdown > .cg-toolbar-gap, .cg-toolbar-right .cg-toolbar-dropdown > .cg-toolbar-gap {
pointer-events: all;
height: 100% !important;
}
/* buttons border-radius (inherit from toolbar defined by user): */
.cg-toolbar-left .cg-toolbar-dropdown:first-child > :first-child,
.cg-toolbar-right .cg-toolbar-dropdown:first-child > :first-child,
.cg-toolbar-bottom .cg-toolbar-dropdown > :last-child,
.cg-toolbar-left .cg-toolbar-group > :first-child,
.cg-toolbar-right .cg-toolbar-group > :first-child {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
.cg-toolbar-left .cg-toolbar-dropdown:last-child > :first-child,
.cg-toolbar-right .cg-toolbar-dropdown:last-child > :first-child,
.cg-toolbar-top .cg-toolbar-dropdown > :last-child,
.cg-toolbar-left .cg-toolbar-group > :last-child,
.cg-toolbar-right .cg-toolbar-group > :last-child {
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
}
.cg-toolbar-top .cg-toolbar-dropdown:first-child > :first-child,
.cg-toolbar-bottom .cg-toolbar-dropdown:first-child > :first-child,
.cg-toolbar-right .cg-toolbar-dropdown > :last-child,
.cg-toolbar-top .cg-toolbar-group > :first-child,
.cg-toolbar-bottom .cg-toolbar-group > :first-child {
border-top-left-radius: inherit;
border-bottom-left-radius: inherit;
}
.cg-toolbar-top .cg-toolbar-dropdown:last-child > :first-child,
.cg-toolbar-bottom .cg-toolbar-dropdown:last-child > :first-child,
.cg-toolbar-left .cg-toolbar-dropdown > :last-child,
.cg-toolbar-top .cg-toolbar-group > :last-child,
.cg-toolbar-bottom .cg-toolbar-group > :last-child {
border-top-right-radius: inherit;
border-bottom-right-radius: inherit;
}
.cg-toolbar-left .cg-toolbar-dropdown.cg-toolbar-checked > :first-child,
.cg-toolbar-left .cg-toolbar-dropdown:hover > :first-child {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
.cg-toolbar-right .cg-toolbar-dropdown.cg-toolbar-checked > :first-child,
.cg-toolbar-right .cg-toolbar-dropdown:hover > :first-child {
border-top-left-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
.cg-toolbar-top .cg-toolbar-dropdown.cg-toolbar-checked > :first-child,
.cg-toolbar-top .cg-toolbar-dropdown:hover > :first-child {
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
.cg-toolbar-bottom .cg-toolbar-dropdown.cg-toolbar-checked > :first-child,
.cg-toolbar-bottom .cg-toolbar-dropdown:hover > :first-child {
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
}
/* maplayers dropdown: */
.cg-toolbar-maplayers {
border-radius: inherit;
font-size: 16px;
}
.cg-toolbar-maplayers > .cg-toolbar-gap {
pointer-events: all;
width: 100% !important;
}
.cg-toolbar-maplayers > .cg-toolbar-checkbox {
text-align: left;
}
/* maplayers subscript index */
.cg-toolbar-maplayers {
counter-reset: layer-index;
}
.cg-toolbar-maplayers .cg-toolbar-button > span:after{
content: counter(layer-index);
vertical-align: sub;
font-size: x-small;
counter-increment: layer-index;
margin-left: 1px;
}
/* maplayers dropdown border-radius: */
.cg-toolbar-left .cg-toolbar-maplayers > :first-child {
border-top-right-radius: inherit;
}
.cg-toolbar-right .cg-toolbar-maplayers > :first-child {
border-top-left-radius: inherit;
}
.cg-toolbar-top .cg-toolbar-maplayers > :first-child {
border-top-right-radius: inherit;
}
.cg-toolbar-bottom .cg-toolbar-maplayers > :last-child {
border-bottom-right-radius: inherit;
}
.cg-toolbar-top .cg-toolbar-maplayers > :last-child {
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
}
.cg-toolbar-left .cg-toolbar-maplayers > :last-child,
.cg-toolbar-right .cg-toolbar-maplayers > :last-child:not(:first-child) {
border-bottom-right-radius: inherit;
}
.cg-toolbar-left .cg-toolbar-maplayers > :last-child:not(:first-child),
.cg-toolbar-right .cg-toolbar-maplayers > :last-child {
border-bottom-left-radius: inherit;
}
.cg-toolbar-bottom .cg-toolbar-maplayers > :first-child {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
import {Units as AGCUnits, NoiseReductionMode} from '@int/geotoolkit/seismic/pipeline/processor/AGC';
import {MementoDeserializationContext} from '@int/geotoolkit/persistence/MementoDeserializationContext';
import {MementoSerializationContext} from '@int/geotoolkit/persistence/MementoSerializationContext';
import {UIRegistry} from '@int/geotoolkit/persistence/UIRegistry';
import {createAjv as create} from 'jsonforms-core';
import cloneDeep from 'lodash/cloneDeep';
import schemas from '@int/geotoolkit/resources/schema';
import set from 'lodash/set';
import {InterpolationType} from '@int/geotoolkit/seismic/pipeline/InterpolationType';
import {NormalizationType} from '@int/geotoolkit/seismic/pipeline/NormalizationType';
import {SeismicColors} from '@int/geotoolkit/seismic/util/SeismicColors';
import {MathUtil} from '@int/geotoolkit/util/MathUtil';
const registry = new UIRegistry();
const colorMaps = SeismicColors.getDefault().listNameColorMaps();
const InterpolationTypeKeys = Object.keys(InterpolationType);
const NormalizationTypeKeys = Object.keys(NormalizationType);
const AGCUnitsKeys = Object.keys(AGCUnits);
const noiseReductionKeys = Object.keys(NoiseReductionMode);
const noiseReductionKey = (value) => noiseReductionKeys.find((key) => NoiseReductionMode[key] === value);
const getAjv = (options) => {
const createAjv = (patch) => {
let schema = JSON.parse(JSON.stringify(schemas));
patch = JSON.parse(JSON.stringify(patch));
const modify = (schema, patch) => {
for (const id in patch) {
if (schema['id'] === id || schema['$id'] === id) {
for (const key in patch[id]) {
const value = patch[id][key];
if (value != null) {
set(schema, key, value);
} else {
delete schema[key];
}
}
}
}
for (const key in schema) {
if (typeof schema[key] === 'object' && schema[key] != null) {
schema[key] = modify(schema[key], patch);
}
}
return schema;
};
if (patch) {
schema = modify(schema, patch);
}
const ajv = create({
multipleOfPrecision: 3,
addUsedSchema: false
});
ajv.addFormat('color', /^((0x){0,1}|#{0,1})([0-9A-F]{8}|[0-9A-F]{6})$/i);
ajv.addSchema(schema);
return ajv;
};
return createAjv({
'/geotoolkit.seismic.widgets.SeismicWidget': {
'charts': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'linestyle': {
'type': 'string',
'label': 'Color',
'format': 'color'
},
'name': {
'type': 'string',
'label': 'Chart name',
'enum': options.chartNames
}
}
}
},
'headers': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'color': {
'type': 'string',
'label': 'Color',
'format': 'color'
},
'name': {
'type': 'string',
'label': 'Chart name',
'enum': options.chartNames
}
}
}
}
},
'/geotoolkit.seismic.pipeline.SeismicPipeline/properties/normalization/properties/scale': {
'minimum': 0.1,
'maximum': 5,
'multipleOf': 0.1,
'default': 0.3
},
'/geotoolkit.seismic.pipeline.SeismicPipeline/properties/colors/properties/colorMap': {
'type': 'string',
'enum': colorMaps
},
'/geotoolkit.seismic.pipeline.processor.AGC/properties/units': {
'type': 'string',
'enum': AGCUnitsKeys
},
'/geotoolkit.seismic.pipeline.processor.AGC/properties/noiseReduction': {
'type': 'string',
'enum': noiseReductionKeys
}
});
};
const getNodeProps = (node) => {
const context = new MementoSerializationContext(null, registry);
const widget = node.getWidget();
context.setObject(widget);
const props = context.getMemento();
props.scale.tracescale = MathUtil.round(props.scale.tracescale, 10);
props.scale.samplescale = MathUtil.round(props.scale.samplescale, 100);
props.pipeline.interpolation.traces.type = InterpolationTypeKeys[props.pipeline.interpolation.traces.type - 1];
props.pipeline.interpolation.samples.type = InterpolationTypeKeys[props.pipeline.interpolation.samples.type - 1];
props.pipeline.normalization.type = NormalizationTypeKeys[props.pipeline.normalization.type];
props.pipeline.normalization.limits.low = MathUtil.round(props.pipeline.normalization.limits.low, 100);
props.pipeline.normalization.limits.high = MathUtil.round(props.pipeline.normalization.limits.high, 100);
props.isServerRendering = true;
if (props.pipeline.dataProcessors.AGC != null) {
props.isServerRendering = false;
props.pipeline.dataProcessors.AGC.units = AGCUnitsKeys[props.pipeline.dataProcessors.AGC.units];
}
props.charts = props.auxiliarychart.charts.map((chart) => ({
linestyle: chart.linestyle,
name: chart.name
}));
const headers = [];
props.axes.headers.fields.forEach((field) => {
if (field.visible) {
headers.push({
color: field.color,
name: field.name
});
}
});
props.headers = headers;
const agcProcess = props.pipeline.processes.find((process) => process.name === 'AGC');
if (agcProcess) {
agcProcess.units = AGCUnitsKeys[agcProcess.units];
agcProcess.noiseReduction = noiseReductionKey(agcProcess.noiseReduction);
}
return props;
};
const setNodeProps = (node, props) => {
props = cloneDeep(props);
const widget = node.getWidget();
const headerNames = node.getChartNames();
props.pipeline.interpolation.traces.type = InterpolationType[props.pipeline.interpolation.traces.type];
props.pipeline.interpolation.samples.type = InterpolationType[props.pipeline.interpolation.samples.type];
props.pipeline.normalization.type = NormalizationType[props.pipeline.normalization.type];
if (!props.isServerRendering) {
props.pipeline.dataProcessors.AGC.units = AGCUnits[props.pipeline.dataProcessors.AGC.units];
}
const charts = [];
props.charts.forEach((chart) => {
if (chart.name !== '') {
charts.push({
linestyle: chart.linestyle,
name: chart.name,
visible: true
});
}
});
props.auxiliarychart.charts = charts;
const fields = headerNames.map((name) => {
const index = props.headers.findIndex((header) => header.name === name);
const color = index !== -1 ? props.headers[index].color || 'black' : 'black';
const visible = index !== -1;
return {color, name, visible};
});
props.axes.headers.fields = fields;
const context = new MementoDeserializationContext(props, registry);
const deserializer = context.getRegistry().getSerializer(widget.getClassName());
if (deserializer != null) {
deserializer.load(context, widget);
widget.invalidate();
}
return props;
};
export {getAjv, getNodeProps, setNodeProps};
<template>
<v-dialog
v-model="showDialog"
persistent
:max-width="480"
>
<v-card>
<v-text-field
v-model="seismicPath"
label="Path to seismic for server"
outlined
dense
:max-width="200"
class="pt-6 pl-2 pr-2"
/>
<v-btn
class="ma-2"
@click="$emit('cancel')"
>
Cancel
</v-btn>
<v-btn
class="primary ma-2"
@click="$emit('apply', seismicPath)"
>
Ok
</v-btn>
</v-card>
</v-dialog>
</template>
<script>
import {VDialog, VCard, VTextField, VBtn} from 'vuetify/lib';
export default {
name: 'PathToSeismicDialog',
components: {VDialog, VCard, VTextField, VBtn},
props: {
showDialog: Boolean,
path: String
},
data () {
return {
seismicPath: this.path
};
},
watch: {
path (val) {
this.path = val;
}
},
methods: {
}
};
</script>
<style scoped>
</style>
<template>
<v-dialog
v-model="showDialog"
max-width="720px"
persistent
style="z-index: 1005;"
@keydown.esc="onClose"
>
<v-card
min-height="700px"
class="d-flex flex-column"
>
<v-card-title
class="headline pb-0"
>
Seismic properties
</v-card-title>
<v-card-text class="pb-0">
<v-container>
<JsonForms
:schema="schema"
:ajv="ajv"
:uischema="uischema"
:data="nodeProps"
:renderers="materialRenderers"
:on-change="applyProperties"
/>
</v-container>
</v-card-text>
<v-spacer />
<v-card-actions>
<v-spacer />
<v-btn
text
@click="onApply"
>
Ok
</v-btn>
<v-btn
text
@click="onClose"
>
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import {JsonForms} from 'jsonforms-vue';
import {materialRenderers} from 'jsonforms-vue-material';
import {VContainer, VDialog} from 'vuetify/lib';
import {uischema} from './uischema.js';
export default {
name: 'SeismicPropertiesDialog',
components: {VContainer, VDialog, JsonForms},
props: {
showDialog: Boolean,
nodeProps: {
type: Object,
default: () => {}
},
ajv: {
type: Object,
default: () => {}
},
schema: {
type: Object,
default: () => {}
}
},
data: function () {
return {
uischema: uischema,
materialRenderers: [],
propertiesData: null
};
},
created () {
this.materialRenderers = [...materialRenderers];
},
methods: {
onClose () {
this.$emit('close');
},
applyProperties (value) {
const {errors, data} = value;
this.propertiesData = errors.length > 0 ? null : data;
},
onApply () {
this.$emit('close', this.propertiesData);
}
}
};
</script>
import {SeismicColors} from '@int/geotoolkit/seismic/util/SeismicColors';
const colorMapItems = {};
SeismicColors.getDefault().listNameColorMaps().forEach((colorMap) => {
colorMapItems[colorMap] = SeismicColors.getDefault().createNamedColorMap(colorMap).exportToImage(320, 20).getCanvas().toDataURL();
});
/* eslint-disable max-len */
const uischema = {
'type': 'Categorization',
'elements': [
{
'type': 'Category',
'label': 'Scale',
'elements': [
{
'type': 'Group',
'label': 'Scaling',
'elements': [
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Traces per inch',
'scope': '#/properties/scale/properties/tracescale'
},
{
'type': 'Control',
'label': 'Inches per second',
'scope': '#/properties/scale/properties/samplescale'
}
]
}
]
},
{
'type': 'Group',
'label': 'Interpolation',
'elements': [
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Samples interpolation type',
'scope': '#/properties/pipeline/properties/interpolation/properties/samples/properties/type'
},
{
'type': 'Control',
'label': 'Traces interpolation type',
'scope': '#/properties/pipeline/properties/interpolation/properties/traces/properties/type'
}
]
}
]
},
{
'type': 'Group',
'label': 'Normalization',
'elements': [
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Type',
'scope': '#/properties/pipeline/properties/normalization/properties/type'
},
{
'type': 'Control',
'label': 'Scale',
'scope': '#/properties/pipeline/properties/normalization/properties/scale',
'options': {'slider': true}
}
]
}
]
},
{
'type': 'Group',
'label': 'Limits',
'elements': [
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Low',
'scope': '#/properties/pipeline/properties/normalization/properties/limits/properties/low'
},
{
'type': 'Control',
'label': 'High',
'scope': '#/properties/pipeline/properties/normalization/properties/limits/properties/high'
}
]
}
]
}
]
},
{
'type': 'Category',
'label': 'Rasterizer',
'elements': [
{
'type': 'Group',
'label': 'Plot type',
'elements': [
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Wiggle',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/Wiggle'
},
{
'type': 'Control',
'label': 'Reversed',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/Reversed'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Positive fill',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/PositiveFill'
},
{
'type': 'Control',
'label': 'Negative fill',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/NegativeFill'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Positive color fill',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/PositiveColorFill'
},
{
'type': 'Control',
'label': 'Negative color fill',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/NegativeColorFill'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Simple density',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/SimpleDensity'
},
{
'type': 'Control',
'label': 'Interpolated density',
'scope': '#/properties/pipeline/properties/plot/properties/type/properties/InterpolatedDensity'
}
]
}
]
},
{
'type': 'Group',
'label': 'Wiggle',
'elements': [
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Clipping factor',
'scope': '#/properties/pipeline/properties/plot/properties/clippingFactor'
},
{
'type': 'Control',
'label': 'Decimation spacing',
'scope': '#/properties/pipeline/properties/plot/properties/decimationSpacing'
}
]
},
{
'type': 'Control',
'label': 'Density decimation',
'scope': '#/properties/pipeline/properties/plot/properties/densityDecimation'
}
]
},
{
'type': 'Group',
'label': 'Colors',
'elements': [
{
'type': 'Control',
'label': 'Color map',
'scope': '#/properties/pipeline/properties/colors/properties/colorMap',
'options': {
'images': true,
'showLabels': true,
'items': colorMapItems
}
}
]
},
{
'type': 'Group',
'label': 'Clipping',
'elements': [
{
'type': 'Control',
'label': 'Clipping Mode',
'scope': '#/properties/pipeline/properties/clippingmode'
}
]
}
]
},
{
'type': 'Category',
'label': 'Auxiliary Chart',
'elements': [
{
'type': 'VerticalLayout',
'elements': [
{
'type': 'Control',
'scope': '#/charts'
}
]
}
]
},
{
'type': 'Category',
'label': 'Header axis',
'elements': [
{
'type': 'VerticalLayout',
'elements': [
{
'type': 'Control',
'scope': '#/headers'
}
]
}
]
},
{
'type': 'Category',
'label': 'Processor',
'rule': {
'effect': 'SHOW',
'condition': {
'scope': '#/isServerRendering',
'schema': {
'const': false
}
}
},
'elements': [
{
'type': 'Expanded',
'scope': '#/properties/pipeline/properties/processes',
'options': {
'draggable': true
},
'elements': [
{
'scope': '#/properties/TaperFilter',
'elements': [
{
'type': 'Control',
'label': 'Enabled',
'scope': '#/properties/apply'
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Freq01',
'scope': '#/properties/f1'
},
{
'type': 'Control',
'label': 'Freq11',
'scope': '#/properties/f2'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Freq02',
'scope': '#/properties/f3'
},
{
'type': 'Control',
'label': 'Freq22',
'scope': '#/properties/f4'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Sample rate',
'scope': '#/properties/sampleRate'
},
{
'type': 'Control',
'label': 'Band-pass mode',
'scope': '#/properties/passFlag'
}
]
}
]
},
{
'scope': '#/properties/AGC',
'elements': [
{
'type': 'Control',
'label': 'Enabled',
'scope': '#/properties/apply'
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'AGC length',
'scope': '#/properties/agcLength'
},
{
'type': 'Control',
'label': 'Desired average',
'scope': '#/properties/desiredAverage'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Noise reduction',
'scope': '#/properties/noiseReduction'
},
{
'type': 'Control',
'label': 'Noise reduction percentage',
'scope': '#/properties/noiseReductionPercentage'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Start sample',
'scope': '#/properties/startSample'
},
{
'type': 'Control',
'label': 'Step',
'scope': '#/properties/step'
}
]
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Units',
'scope': '#/properties/units'
},
{
'type': 'Control',
'label': 'Window length',
'scope': '#/properties/windowLength'
}
]
}
]
},
{
'scope': '#/properties/Reverse',
'elements': [
{
'type': 'Control',
'label': 'Enabled',
'scope': '#/properties/apply'
},
{
'type': 'HorizontalLayout',
'elements': [
{
'type': 'Control',
'label': 'Inverted',
'scope': '#/properties/inverted'
},
{
'type': 'Control',
'label': 'Reversed',
'scope': '#/properties/reversed'
}
]
}
]
}
]
}
]
}
]
};
export {uischema};
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
</div> </div>
<toolbar-controls :plots="plots" :data-loaded="isWidgetReady" <toolbar-controls :plots="plots" :data-loaded="isWidgetReady"
:show-line-style-panel="showLineStylePanel" @toggleLineStylePanel="toggleLineStylePanel" :show-line-style-panel="showLineStylePanel" @toggleLineStylePanel="toggleLineStylePanel"
@exporting="exporting = $event" @closePrintDialog="showPrintDialog = false" /> @exporting="exporting = $event" @closePrintDialog="showPrintDialog = false"/>
<el-tooltip content="绘制文本" placement="bottom" effect="light"> <el-tooltip content="绘制文本" placement="bottom" effect="light">
<el-button @click="toggleDrawText" :class="{ 'active': isDrawingText }"> <el-button @click="toggleDrawText" :class="{ 'active': isDrawingText }">
...@@ -36,9 +36,14 @@ ...@@ -36,9 +36,14 @@
<i class="el-icon-edit"></i> <i class="el-icon-edit"></i>
</el-button> </el-button>
</el-tooltip> </el-tooltip>
<el-tooltip content="设置" placement="bottom" effect="light">
<el-button @click="editProperties" :class="{ 'active': showLineStylePanel }">
<i class="el-icon-setting"></i>
</el-button>
</el-tooltip>
</div> </div>
</div> </div>
<canvas ref="plot" id="canvas" /> <canvas ref="plot" id="canvas"/>
<!-- 添加鼠标悬停专用覆盖层 --> <!-- 添加鼠标悬停专用覆盖层 -->
<div ref="hoverLayer" class="hover-layer"></div> <div ref="hoverLayer" class="hover-layer"></div>
<!-- 自定义右键菜单 --> <!-- 自定义右键菜单 -->
...@@ -202,45 +207,66 @@ ...@@ -202,45 +207,66 @@
</div> </div>
</div> </div>
</div> </div>
<PropertiesDialog
:show-dialog="showPropertiesDialog"
:node-props="nodeProps"
:ajv="ajv"
:schema="schema"
@close="applyProps"
/>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { SeismicWidget } from '@int/geotoolkit/seismic/widgets/SeismicWidget'; import {SeismicWidget} from '@int/geotoolkit/seismic/widgets/SeismicWidget';
import { SeismicColors } from '@int/geotoolkit/seismic/util/SeismicColors'; import {SeismicColors} from '@int/geotoolkit/seismic/util/SeismicColors';
import { SeismicPipeline } from '@int/geotoolkit/seismic/pipeline/SeismicPipeline'; import {SeismicPipeline} from '@int/geotoolkit/seismic/pipeline/SeismicPipeline';
import { SegyReader } from '@int/geotoolkit/seismic/data/SegyReader'; import {SegyReader} from '@int/geotoolkit/seismic/data/SegyReader';
import { LocalFile } from '@int/geotoolkit/seismic/data/LocalFile'; import {LocalFile} from '@int/geotoolkit/seismic/data/LocalFile';
import { Plot } from '@int/geotoolkit/plot/Plot'; import {Plot} from '@int/geotoolkit/plot/Plot';
import { getToken } from '@/utils/auth'; import {getToken} from '@/utils/auth';
import { Group } from '@int/geotoolkit/scene/Group'; import {Group} from '@int/geotoolkit/scene/Group';
import { Paint } from '@int/geotoolkit/controls/tools/Paint'; import {Paint} from '@int/geotoolkit/controls/tools/Paint';
import { PaintMode } from '@int/geotoolkit/controls/tools/PaintMode'; import {PaintMode} from '@int/geotoolkit/controls/tools/PaintMode';
import { EditEvents } from '@int/geotoolkit/controls/tools/EditEvents'; import {EditEvents} from '@int/geotoolkit/controls/tools/EditEvents';
import { EditMode } from '@int/geotoolkit/controls/tools/EditMode'; import {EditMode} from '@int/geotoolkit/controls/tools/EditMode';
import { Selection, Events as SelectionEvents } from '@int/geotoolkit/controls/tools/Selection'; import {Selection, Events as SelectionEvents} from '@int/geotoolkit/controls/tools/Selection';
import { TextStyle } from '@int/geotoolkit/attributes/TextStyle'; import {TextStyle} from '@int/geotoolkit/attributes/TextStyle';
import { LineStyle } from '@int/geotoolkit/attributes/LineStyle'; import {LineStyle} from '@int/geotoolkit/attributes/LineStyle';
import { FillStyle } from '@int/geotoolkit/attributes/FillStyle'; import {FillStyle} from '@int/geotoolkit/attributes/FillStyle';
import { Text } from '@int/geotoolkit/scene/shapes/Text'; import {Text} from '@int/geotoolkit/scene/shapes/Text';
import { NormalizationType } from '@int/geotoolkit/seismic/pipeline/NormalizationType'; import {NormalizationType} from '@int/geotoolkit/seismic/pipeline/NormalizationType';
import { NoSnapPicking } from '@int/geotoolkit/seismic/data/snap/NoSnapPicking'; import {NoSnapPicking} from '@int/geotoolkit/seismic/data/snap/NoSnapPicking';
import { SnapPicker } from '@int/geotoolkit/seismic/data/snap/SnapPicker'; import {SnapPicker} from '@int/geotoolkit/seismic/data/snap/SnapPicker';
import { ColorBarLocation } from '@int/geotoolkit/controls/shapes/ColorBarLocation'; import {ColorBarLocation} from '@int/geotoolkit/controls/shapes/ColorBarLocation';
import { Alignment as BoxLayoutAlignment } from '@int/geotoolkit/layout/BoxLayout'; import {Alignment as BoxLayoutAlignment} from '@int/geotoolkit/layout/BoxLayout';
import { LINE_PATTERNS, FILL_PATTERNS, TEXT_PATTERNS, LINESTYLE_PATTERNS, IMAGE_PATTERNS, LS_KEYS, FS_KEYS, TS_KEYS } from '@/api/Patterns.js'; import {
import { SizeMode } from '@int/geotoolkit/scene/shapes/Text'; LINE_PATTERNS,
import { RgbaColor } from '@int/geotoolkit/util/RgbaColor'; FILL_PATTERNS,
import { AutoNumberFormat } from '@int/geotoolkit/util/AutoNumberFormat'; TEXT_PATTERNS,
LINESTYLE_PATTERNS,
IMAGE_PATTERNS,
LS_KEYS,
FS_KEYS,
TS_KEYS
} from '@/api/Patterns.js';
import {SizeMode} from '@int/geotoolkit/scene/shapes/Text';
import {RgbaColor} from '@int/geotoolkit/util/RgbaColor';
import {AutoNumberFormat} from '@int/geotoolkit/util/AutoNumberFormat';
// 导入新的组件 // 导入新的组件
import ToolbarControls from '@/components/ToolbarControls.vue'; import ToolbarControls from '@/components/ToolbarControls.vue';
import LineStylePanel from '@/components/LineStylePanel.vue'; import LineStylePanel from '@/components/LineStylePanel.vue';
import { CrossHair, Events as CrossHairEvents } from '@int/geotoolkit/controls/tools/CrossHair'; import {CrossHair, Events as CrossHairEvents} from '@int/geotoolkit/controls/tools/CrossHair';
import { TaperFilterProcess } from '@int/geotoolkit/seismic/analysis/filters/TaperFilterProcess'; import {TaperFilterProcess} from '@int/geotoolkit/seismic/analysis/filters/TaperFilterProcess';
import { AGC } from '@int/geotoolkit/seismic/pipeline/processor/AGC'; import {AGC} from '@int/geotoolkit/seismic/pipeline/processor/AGC';
import { Reverse } from '@int/geotoolkit/seismic/pipeline/processor/Reverse'; import {Reverse} from '@int/geotoolkit/seismic/pipeline/processor/Reverse';
import { Path } from '@int/geotoolkit/scene/shapes/Path'; import {Path} from '@int/geotoolkit/scene/shapes/Path';
import {rgb} from "chalk";
import PathToSeismicDialog from '../plots/ui/PathToSeismicDialog.vue';
import {getAjv, setNodeProps, getNodeProps} from '../plots/ui/DialogPropertyUtils';
import PropertiesDialog from '../plots/ui/PropertiesDialog.vue';
// 线条样式模式常量 // 线条样式模式常量
const TEXT_PATTERN_KEYS = Object.keys(TEXT_PATTERNS); const TEXT_PATTERN_KEYS = Object.keys(TEXT_PATTERNS);
...@@ -297,22 +323,13 @@ export default { ...@@ -297,22 +323,13 @@ export default {
name: "seismic", name: "seismic",
components: { components: {
ToolbarControls, ToolbarControls,
LineStylePanel LineStylePanel,
PropertiesDialog
}, },
data() { data() {
return { return {
plots: null, plots: null,
_seismicWidget: null, _seismicWidget: null,
pipeline: null,
isHovering: false,
cursorInfo: {
depth: null,
trace: null,
value: null
},
showCursorInfo: true,
isWidgetReady: false,
loadingError: null,
_headers: [], _headers: [],
_colorMap: null, _colorMap: null,
savedLineAnnotations: [{ savedLineAnnotations: [{
...@@ -358,7 +375,7 @@ export default { ...@@ -358,7 +375,7 @@ export default {
// 添加模拟数据 // 添加模拟数据
savedAnnotations: [{ savedAnnotations: [{
type: "unknown", type: "unknown",
text: "发发发", // text: "发发发",
properties: { properties: {
id: null, id: null,
name: "", name: "",
...@@ -430,7 +447,7 @@ export default { ...@@ -430,7 +447,7 @@ export default {
mindimension: null, mindimension: null,
maxdimension: null, maxdimension: null,
layoutstyle: null, layoutstyle: null,
text: "发发发", // text: "发发发",
textstyle: { textstyle: {
links: { links: {
Invalidate: { Invalidate: {
...@@ -523,10 +540,10 @@ export default { ...@@ -523,10 +540,10 @@ export default {
// 更新颜色映射选择器 // 更新颜色映射选择器
currentColorMap: 'WhiteBlack', // 默认使用黑白渐变 currentColorMap: 'WhiteBlack', // 默认使用黑白渐变
colorMaps: [ colorMaps: [
{ value: 'WhiteBlack', label: '黑白渐变' }, {value: 'WhiteBlack', label: '黑白渐变'},
{ value: 'CustomGrayScale', label: '灰度渐变' }, {value: 'CustomGrayScale', label: '灰度渐变'},
{ value: 'CustomRedScale', label: '红色渐变' }, {value: 'CustomRedScale', label: '红色渐变'},
{ value: 'BlueWhiteRed', label: '蓝白红渐变' }, {value: 'BlueWhiteRed', label: '蓝白红渐变'},
// { value: 'Rainbow', label: '彩虹渐变' }, // { value: 'Rainbow', label: '彩虹渐变' },
// { value: 'Jet', label: 'Jet渐变' }, // { value: 'Jet', label: 'Jet渐变' },
// { value: 'Hot', label: '热力图' }, // { value: 'Hot', label: '热力图' },
...@@ -594,7 +611,7 @@ export default { ...@@ -594,7 +611,7 @@ export default {
shortcut: 'Ctrl+Y', shortcut: 'Ctrl+Y',
action: 'redo' action: 'redo'
}, },
{ type: 'separator' }, {type: 'separator'},
{ {
text: '复制', text: '复制',
icon: 'mdi-content-copy', icon: 'mdi-content-copy',
...@@ -617,6 +634,13 @@ export default { ...@@ -617,6 +634,13 @@ export default {
clipboard: null, // 用于存储复制的路径 clipboard: null, // 用于存储复制的路径
undoStack: [], // 撤销栈 undoStack: [], // 撤销栈
redoStack: [], // 重做栈 redoStack: [], // 重做栈
showPropertiesDialog: false,
nodeProps: null,
ajv: null,
schema: null,
}; };
}, },
mounted() { mounted() {
...@@ -756,6 +780,18 @@ export default { ...@@ -756,6 +780,18 @@ export default {
'options': { 'options': {
'minimumSpan': 100 'minimumSpan': 100
} }
},
// 新增:视图层禁用分档渲染
'rendering': {
'amplitudeBinning': { 'enabled': false }, // 核心:禁用视图级振幅分档
'useContinuousAmplitude': true, // 核心:使用连续振幅映射
'antiAlias': true, // 优化:启用抗锯齿(连续渲染更平滑)
'pixelRatio': window.devicePixelRatio || 1, // 适配高分辨率屏幕
'lineWidth': 1.2 // 轻微增加线条宽度(避免细线条在白色背景下消失)
},
'dataProcessing': {
'preserveRawAmplitude': true, // 核心:Widget 不二次处理振幅
'skipAmplitudeAdjustment': true // 核心:跳过任何隐性振幅调整
} }
} }
}) })
...@@ -769,7 +805,7 @@ export default { ...@@ -769,7 +805,7 @@ export default {
// 初始化默认的颜色映射,使用256色以获得更平滑的渐变 // 初始化默认的颜色映射,使用256色以获得更平滑的渐变
this._colorMap = this.colorProvider.createNamedColorMap('WhiteBlack', 256); this._colorMap = this.colorProvider.createNamedColorMap('WhiteBlack', 256);
console.log(this._colorMap)
// 加载数据 // 加载数据
this.$nextTick(() => { this.$nextTick(() => {
...@@ -820,10 +856,15 @@ export default { ...@@ -820,10 +856,15 @@ export default {
throw new Error('获取到的文件数据为空'); throw new Error('获取到的文件数据为空');
} }
let filesObj = new File([blob], fileName, { type: blob.type, lastModified: Date.now() }); let filesObj = new File([blob], fileName, {type: blob.type, lastModified: Date.now()});
const file = new LocalFile(filesObj); const file = new LocalFile(filesObj);
const segyReader = new SegyReader(file); const segyReader = new SegyReader(file, {
disableAmplitudeBinning: true, // 核心:禁用解析阶段分档
amplitudeClipping: false, // 核心:保留振幅极值
autoGainControl: false, // 核心:不修改原始振幅大小
// 删除可能存在的“分档相关冗余参数”(如 binCount、binSize 等)
});
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
segyReader.loadMetaData((reader) => { segyReader.loadMetaData((reader) => {
if (reader instanceof Error) { if (reader instanceof Error) {
...@@ -860,17 +901,28 @@ export default { ...@@ -860,17 +901,28 @@ export default {
.setOptions({ .setOptions({
'normalization': { 'normalization': {
'type': NormalizationType.RMS, 'type': NormalizationType.RMS,
'scale': 0.4 'scale': 0.3,
'preserveRawAmplitude': true // 核心:强制保留原始振幅
}, },
'plot': { 'plot': {
'type': { 'type': {
'Wiggle': false, 'Wiggle': false,
'InterpolatedDensity': true 'InterpolatedDensity': true
}, },
'decimationSpacing': 5 'decimationSpacing': 5,
'disableAmplitudeBinning': true
}, },
'colors': { 'colors': {
'colorMap': this._colorMap 'colorMap': this._colorMap,
'colorMappingType': 'continuous', // 核心:颜色映射为连续模式(非分档)
'interpolateColors': true // 新增:启用颜色插值(确保振幅值与颜色无缝过渡)
},
'amplitude': {
'enableBinning': false, // 核心:全局禁用振幅分档
'clipAmplitude': false, // 核心:不截断任何振幅值(保留极值)
'clipPercentage': 0.5, // 仅截断0.5%的极端值(保留99%有效数据)
'useRawValues': true, // 核心:强制使用原始振幅值渲染
'gain': 1.2
} }
}); });
...@@ -889,6 +941,15 @@ export default { ...@@ -889,6 +941,15 @@ export default {
'visible': true, 'visible': true,
'text': pipeline.getName() 'text': pipeline.getName()
} }
},
'rendering': {
'amplitudeBinning': {'enabled': false}, // 核心:Widget 渲染禁用分档
'useContinuousAmplitude': true, // 核心:使用连续振幅映射
'antiAlias': true // 新增:启用抗锯齿(优化连续颜色显示效果)
},
'dataProcessing': {
'preserveRawAmplitude': true, // 核心:Widget 不二次处理振幅
'skipAmplitudeAdjustment': true // 新增:跳过任何振幅调整(避免隐性修改)
} }
} }
}); });
...@@ -896,8 +957,13 @@ export default { ...@@ -896,8 +957,13 @@ export default {
// Now add processors one by one // Now add processors one by one
try { try {
pipeline.addTraceProcessor(new TaperFilterProcess({ pipeline.addTraceProcessor(new TaperFilterProcess({
'apply': false, 'apply': true,
'name': 'TaperFilter' 'sampleRate': 1,
'passFlag': true,
'f1': 0, // 低频截止(保留所有低频)
'f2': 15, // 低频过渡带
'f3': 16, // 高频过渡带
'f4': 30 // 高频截止(保留 30Hz 以下信号,避免噪声干扰)
})); }));
} catch (e) { } catch (e) {
console.warn('Failed to add TaperFilter:', e); console.warn('Failed to add TaperFilter:', e);
...@@ -913,14 +979,13 @@ export default { ...@@ -913,14 +979,13 @@ export default {
} }
try { try {
pipeline.addTraceProcessor(new Reverse({ // Reverse(振幅反转):禁用(不改变原始振幅极性)
'apply': false, pipeline.addTraceProcessor(new Reverse({'apply': false, 'name': 'Reverse'}));
'name': 'Reverse'
}));
} catch (e) { } catch (e) {
console.warn('Failed to add Reverse:', e); console.warn('Failed to add Reverse:', e);
} }
this._seismicWidget.fitToBounds(); this._seismicWidget.fitToBounds();
this.isWidgetReady = true; this.isWidgetReady = true;
resolve(); resolve();
...@@ -935,11 +1000,6 @@ export default { ...@@ -935,11 +1000,6 @@ export default {
}); });
}, },
handleMouseMove(event) {
if (!this._seismicWidget || !this.isHovering) return;
// 使用内置状态栏,不需要额外的处理逻辑
},
onFileOpen(evt, plot, fileInfo) { onFileOpen(evt, plot, fileInfo) {
evt.stopPropagation(); evt.stopPropagation();
...@@ -1186,7 +1246,7 @@ export default { ...@@ -1186,7 +1246,7 @@ export default {
}); });
// 保存当前状态用于下次比较 // 保存当前状态用于下次比较
node._previousState = { node._previousState = {
properties: { ...node.getProperties() }, properties: {...node.getProperties()},
textStyle: textStyle ? { textStyle: textStyle ? {
font: textStyle.getFont(), font: textStyle.getFont(),
color: textStyle.getColor(), color: textStyle.getColor(),
...@@ -1628,7 +1688,7 @@ export default { ...@@ -1628,7 +1688,7 @@ export default {
try { try {
// 验证freezeupdate设置是否正常工作 // 验证freezeupdate设置是否正常工作
this._seismicWidget.setOptions({ 'freezeupdate': false }); this._seismicWidget.setOptions({'freezeupdate': false});
} catch (error) { } catch (error) {
console.error('设置widget选项失败:', error); console.error('设置widget选项失败:', error);
this.loadingError = `Widget选项设置失败: ${error.message}`; this.loadingError = `Widget选项设置失败: ${error.message}`;
...@@ -1761,9 +1821,9 @@ export default { ...@@ -1761,9 +1821,9 @@ export default {
// 白色到黑色的渐变 // 白色到黑色的渐变
interpolate(colors, 0, 255, { interpolate(colors, 0, 255, {
A: 255, A: 255,
R: 255, R: 240,
G: 255, G: 240,
B: 255 B: 240
}, { }, {
A: 255, A: 255,
R: 0, R: 0,
...@@ -2578,7 +2638,7 @@ export default { ...@@ -2578,7 +2638,7 @@ export default {
console.log(`恢复文本标注 ${index + 1}/${this.savedAnnotations.length}:`, { console.log(`恢复文本标注 ${index + 1}/${this.savedAnnotations.length}:`, {
text: data.text || data.properties.text, text: data.text || data.properties.text,
position: { x: data.properties.ax, y: data.properties.ay } position: {x: data.properties.ax, y: data.properties.ay}
}); });
} catch (error) { } catch (error) {
console.error(`恢复文本标注 ${index + 1} 时出错:`, { console.error(`恢复文本标注 ${index + 1} 时出错:`, {
...@@ -2784,7 +2844,22 @@ export default { ...@@ -2784,7 +2844,22 @@ export default {
} }
return changes; return changes;
},
applyProps (props) {
if (props) {
setNodeProps(seismicPlot, props);
} }
this.showPropertiesDialog = false;
},
editProperties () {
var seismicPlot =this.plots
this.ajv = getAjv({chartNames: seismicPlot.getChartNames()});
this.schema = this.ajv.getSchema(`/${seismicPlot.getWidget().getClassName()}`).schema;
this.nodeProps = getNodeProps(seismicPlot);
this.showPropertiesDialog = true;
},
}, },
beforeDestroy() { beforeDestroy() {
...@@ -3153,15 +3228,10 @@ export default { ...@@ -3153,15 +3228,10 @@ export default {
.CustomGrayScale { .CustomGrayScale {
background: linear-gradient(to right, background: linear-gradient(to right,
rgb(255, 255, 255) 50%, rgb(255, 255, 255) 50%,
/* -4000到181保持白色 */ /* -4000到181保持白色 */ rgb(253, 253, 253) 55%,
rgb(253, 253, 253) 55%, /* 181开始的颜色 */ rgb(240, 240, 240) 65%,
/* 181开始的颜色 */ /* 到566的颜色 */ rgb(180, 180, 180) 80%,
rgb(240, 240, 240) 65%, /* 566后的过渡色 */ rgb(6, 6, 6) 100% /* 最终颜色 */
/* 到566的颜色 */
rgb(180, 180, 180) 80%,
/* 566后的过渡色 */
rgb(6, 6, 6) 100%
/* 最终颜色 */
); );
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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