This tutorial provides a way to compare two different seismic layers on the same plot using the Comparator tool geotoolkit/seismic/widgets/tools/Comparator.
# Creating Layers
This tutorial shows how to create different layers within a plot. The following example uses geotoolkit/scene/Group to group layers as necessary. The position of the images can be changed with changeChildOrder() which organizes all the indexes of a group.
# Comparing Seismic Plots using Layers
The following example uses RemoteSeismicReader to read data from the server. It retrieves a slice of one inline data set from the server and displays it with SeismicWidget. To display a second seismic plot in the widget, create an additional pipeline by using the clone() method. The Comparator tool is then initialized for the widget.
# Layer Orientation
The layer orientation can be specified using the setOrientation method.
# Layer Transparency
The layer transparency can be specified using the setOptions method on the pipeline.
# Source code
import { Orientation } from "@int/geotoolkit/util/Orientation.ts";
import { NodeOrder } from "@int/geotoolkit/scene/CompositeNode.ts";
import { SeismicImage } from "@int/geotoolkit/seismic/image/SeismicImage.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { SeismicWidget } from "@int/geotoolkit/seismic/widgets/SeismicWidget.ts";
import { SeismicColors } from "@int/geotoolkit/seismic/util/SeismicColors.ts";
import { NormalizationType } from "@int/geotoolkit/seismic/pipeline/NormalizationType.ts";
import { SeismicPipeline } from "@int/geotoolkit/seismic/pipeline/SeismicPipeline.ts";
import { RemoteSeismicDataSource } from "@int/geotoolkit/seismic/data/RemoteSeismicDataSource.ts";
const plots = [];
function createSectionQuery(position, key, oppositeKey) {
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 {
"keys": selectKeys,
"options": null,
"emptyTracesKey": {
"name": oppositeKey["key"],
"min": oppositeKey["min"],
"max": oppositeKey["max"]
}
};
}
const createReader = function(options, onready, onfailure) {
const data = new RemoteSeismicDataSource({
"host": options["host"],
"file": options["source"],
"version": 2
});
data.open(
() => {
const keys = data.getKeys();
const key = keys[0];
const oppositeKey = keys[1];
const query = createSectionQuery(options["inline"], key, oppositeKey);
data.select(query, onready, onfailure);
},
onfailure
);
};
const createPipeline = function(reader) {
return new SeismicPipeline({
"name": "Seismic",
"reader": reader,
"statistics": reader.getStatistics()
}).setOptions({
"normalization": {
"type": NormalizationType.RMS,
"scale": 0.4
},
"plot": {
"type": {
"wiggle": false,
"interpolateddensity": true
},
"decimationspacing": 5
},
"colors": {
"colormap": SeismicColors.getDefault().createNamedColorMap("WhiteBlack", 32)
}
});
};
function initializeLayerTool(widget, pipeline) {
pipeline = pipeline.clone().setOptions({
"normalization": {
"type": NormalizationType.RMS,
"scale": 0.4
},
"plot": {
"type": {
"wiggle": false,
"interpolateddensity": true
},
"decimationspacing": 5
},
"colors": {
"colormap": SeismicColors.getDefault().createNamedColorMap("BlackRedYellowWhite", 32),
"opacity": 1
}
});
return widget.getToolByName("comparator").setEnabled(true).setPipeline(pipeline);
}
function createWidget(canvas, pipeline, secondPipeline) {
const widget = new SeismicWidget({
"pipeline": pipeline,
"colorbar": {
"axis": {
"tickgenerator": {
"edge": {
"tickvisible": false,
"labelvisible": false
}
}
}
},
"layouttype": "inside",
"statusbar": {
"visible": false
}
}).setScaleOptions({
"tracescale": 20,
"samplescale": 200,
"deviceunit": "in",
"sampleunit": "ft"
});
const headerFields = pipeline.getReader().getTraceHeaderFields();
let header, headerInfo;
for (let i = 0; i < headerFields.length; i++) {
header = headerFields[i];
if (header.getName() === "XLINE") {
widget.setTraceHeaderVisible(header, true);
} else if (header.getName() === "TraceNumber") {
widget.setTraceHeaderVisible(header, false);
}
headerInfo = widget.getTraceHeaderAxis(header);
if (headerInfo) {
headerInfo["label"].getTextStyle().setColor("#6b6b6b");
}
}
if (secondPipeline) {
initializeLayerTool(widget, secondPipeline);
}
plots.push(new Plot({
"canvaselement": canvas,
"root": widget
}));
return widget;
}
let firstSeismicImage, secondSeismicImage, layeredWidget;
function createSeismicLayers(reader, canvas) {
const pipeline = createPipeline(reader);
pipeline.setOptions({ "colors": {
"colormap": SeismicColors.getDefault().createNamedColorMap("BlackRedYellowWhite", 32)
} });
const secondPipeline = createPipeline(reader);
secondPipeline.setOptions({ "plot": {
"type": {
"wiggle": true,
"interpolateddensity": false,
"simpledensity": false
},
"decimationspacing": 5
} });
const modelLimits = secondPipeline.getModelLimits();
layeredWidget = createWidget(canvas, pipeline);
layeredWidget.setOptions({
"autoseismiclimits": false
});
layeredWidget.setSeismicModelLimits(modelLimits);
firstSeismicImage = layeredWidget.getSeismicImage();
firstSeismicImage.setBounds(modelLimits);
const parentSeismicGroup = layeredWidget.getSeismicModel();
secondSeismicImage = new SeismicImage(secondPipeline);
secondSeismicImage.setBounds(modelLimits);
parentSeismicGroup.addChild(secondSeismicImage);
}
function toggleOrder() {
if (firstSeismicImage && secondSeismicImage) {
const parentSeismicGroup = layeredWidget.getSeismicModel();
parentSeismicGroup.changeChildOrder(
firstSeismicImage,
parentSeismicGroup.indexOfChild(secondSeismicImage) > parentSeismicGroup.indexOfChild(firstSeismicImage) ? NodeOrder.Forward : NodeOrder.Backward
);
}
}
function initialize(transparentLayer, verticalComparison, horizontalComparison, transparentComparison) {
const MAJOR_INLINE = 1;
const MINOR_INLINE = 25;
const DATA_HOST = "https://demo.int.com/INTGeoServer/json";
const DATA_SOURCE = "data/seismic/Gullfaks_Amplitude.xgy";
createReader({
"host": DATA_HOST,
"source": DATA_SOURCE,
"inline": MAJOR_INLINE
}, (reader) => {
createReader({
"host": DATA_HOST,
"source": DATA_SOURCE,
"inline": MINOR_INLINE
}, (secondReader) => {
let pipeline = createPipeline(reader);
const secondPipeline = createPipeline(secondReader);
createSeismicLayers(reader, transparentLayer);
createWidget(verticalComparison, pipeline, secondPipeline);
createWidget(horizontalComparison, pipeline, secondPipeline).getToolByName("comparator").setOrientation(Orientation.Horizontal);
const widget = createWidget(transparentComparison, pipeline, secondPipeline);
pipeline = widget.getPipeline().clone().setOptions({
"colors": {
"colormap": SeismicColors.getDefault().createNamedColorMap("RedWhiteBlack", 32)
}
});
widget.setPipeline(pipeline);
const comparator = widget.getToolByName("comparator").setSplit(false).setContinuous(true);
comparator.getPipeline().setOptions({
"plot": {
"type": {
"wiggle": true,
"interpolateddensity": false
}
},
"colors": {
"colormap": SeismicColors.getDefault().createNamedColorMap("BlackRedYellowWhite", 32),
"opacity": 0.5
}
});
}, (error) => {
alert(error);
});
}, (error) => {
alert(error);
});
}
function dispose() {
plots.forEach((plot) => plot.dispose());
}
export { dispose, initialize, toggleOrder };
createScene();