Seismic Movie Mode

This example shows movie mode. It is possible to navigate forwad or backward slice by slice or start automatically loading slices. "freezeupdate" mode in seismic widget allows keeping the current image during loading the next one. In "Play" mode seismic data is requested each 3 seconds.

# Result

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";
import { Events } from "@int/geotoolkit/scene/shapes/tiledshape/Events.ts";
const FrameTimeInterval = 3e3;
const 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 createDataSource = async () => {
  const host = "https://demo.int.com/INTGeoServer/json";
  return new Promise((resolve, reject) => {
    const data = new RemoteSeismicDataSource({
      "host": host,
      "file": "data/seismic/Gullfaks_Amplitude.xgy",
      "version": 2
    });
    data.open(() => {
      resolve(data);
    }, (err) => {
      reject(err);
    });
  });
};
const createReader = async (data, position) => {
  const keys = data.getKeys();
  const key = keys[0];
  const oppositeKey = keys[1];
  const query = createSectionQuery(position, key, oppositeKey);
  return new Promise((resolve, reject) => {
    data.select(query, (reader) => {
      resolve(reader);
    });
  });
};
const createPipeline = function(reader) {
  const pipeline = new SeismicPipeline({
    "name": "Seismic",
    "reader": reader,
    "statistics": reader.getStatistics()
  });
  pipeline.setOptions({
    "normalization": {
      "type": NormalizationType.RMS,
      "scale": 1
    },
    "plot": {
      "type": {
        "wiggle": false,
        "interpolateddensity": true
      },
      "decimationspacing": 5
    },
    "colors": {
      "colormap": SeismicColors.getDefault().createNamedColorMap("WhiteBlack", 32)
    }
  });
  return pipeline;
};
class SeismicMovie {
  constructor(canvas, errorObj) {
    this.errorObj = errorObj;
    this.lastTileRendered = true;
    this.widget = new SeismicWidget({
      "colorbar": {
        "axis": {
          "tickgenerator": {
            "edge": {
              "tickvisible": false,
              "labelvisible": false
            }
          }
        }
      },
      "layouttype": "inside",
      "statusbar": {
        "visible": false
      },
      "table": {
        "size": 100,
        "visible": false
      },
      "freezeupdate": true
    });
    this.plot = new Plot({
      "canvaselement": canvas,
      "root": this.widget
    });
  }
  async create() {
    try {
      this.data = await createDataSource();
      const keys = this.data.getKeys();
      this.key = keys[0];
      this.position = this.key["min"];
      const reader = await createReader(this.data, this.position);
      const pipeline = createPipeline(reader);
      this.widget.setPipeline(pipeline);
      this.widget.on(Events.LastTileRendered, () => {
        this.lastTileRendered = true;
      });
      this.widget.setScaleOptions({
        "tracescale": 20,
        "samplescale": 200,
        "deviceunit": "in",
        "sampleunit": "ft"
      });
      const headerFields = pipeline.getReader().getTraceHeaderFields();
      let headerInfo;
      for (let i = 0; i < headerFields.length; i++) {
        const header = headerFields[i];
        if (header.getName() === "INLINE" || header.getName() === "XLINE") {
          this.widget.setTraceHeaderVisible(header, true);
        } else if (header.getName() === "TraceNumber") {
          this.widget.setTraceHeaderVisible(header, false);
        }
        headerInfo = this.widget.getTraceHeaderAxis(header);
        if (headerInfo) {
          headerInfo["label"].getTextStyle().setColor("#6b6b6b");
        }
      }
    } catch (err) {
      this.showError(err);
    }
  }
  async forward() {
    try {
      const keys = this.data.getKeys();
      const key = keys[0];
      if (this.position + 1 <= key["max"]) {
        const reader = await createReader(this.data, this.position + 1);
        const pipeline = createPipeline(reader);
        this.lastTileRendered = false;
        this.widget.setPipeline(pipeline, false);
        this.position++;
      }
    } catch (err) {
      this.stop();
      this.showError(err);
    }
  }
  async backward() {
    try {
      const keys = this.data.getKeys();
      const key = keys[0];
      if (this.position - 1 >= key["min"]) {
        const reader = await createReader(this.data, this.position - 1);
        const pipeline = createPipeline(reader);
        this.lastTileRendered = false;
        this.widget.setPipeline(pipeline, false);
        this.position--;
      }
    } catch (err) {
      this.stop();
      this.showError(err);
    }
  }
  async play() {
    if (!this.intervalId) {
      this.intervalId = window.setInterval(() => {
        if (this.lastTileRendered) {
          const keys = this.data.getKeys();
          const key = keys[0];
          if (this.position + 1 > key["max"]) {
            this.position = key["min"];
          }
          this.forward();
        }
      }, FrameTimeInterval);
    }
  }
  async stop() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  }
  dispose() {
    this.plot.dispose();
  }
  showError(error) {
    this.errorObj.show = true;
    this.errorObj.text = typeof error === "object" || error.name ? error.name : error;
  }
}
function createScene(canvas, errorObj) {
  const movie = new SeismicMovie(canvas, errorObj);
  movie.create();
  return movie;
}
export { createScene };

createScene(document.querySelector('[ref="plot"]'), this.error);

Close