Interactive Labeling

This tutorial shows how to do manual (programmatic or interactive) labeling on geotoolkit/schematics/widgets/CompositeSchematicsWidget. It demonstrates also how to make those labels' vertical (measured depth) position following ViewMode changes. The example provides exporting all the labels to PDF with default settings.

# Widget Initialization

import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { WellBoreData } from "@int/geotoolkit/schematics/data/WellBoreData.ts";
import { CompositeSchematicsWidget } from "@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts";
import { AnnotationHelper } from "/src/code/Schematics/InteractiveLabeling/AnnotationHelper.ts";
import { Alignment } from "@int/geotoolkit/layout/BoxLayout.ts";
import { FixedTrackWidthStrategy } from "@int/geotoolkit/schematics/FixedTrackWidthStrategy.ts";
import { LocationType } from "@int/geotoolkit/schematics/labeling/LocationType.ts";
import { ViewMode } from "@int/geotoolkit/schematics/scene/WellBoreNode.ts";
import { LabelsFilter } from "@int/geotoolkit/schematics/labeling/LabelsFilter.ts";
import { obfuscate } from "@int/geotoolkit/lib.js";
import { ComponentUtils } from "@int/geotoolkit/schematics/utils/ComponentUtils.ts";
import { ScalingOptions } from "@int/geotoolkit/scene/exports/ScalingOptions.ts";
import { deepMergeObject } from "@int/geotoolkit/base.js";
import data from "/src/assets/data/wellBoreData.json?import";
const WEST_AXIS_WIDTH = 70;
const SCHEMATICS_WIDTH = 100;
const SCHEMATICS_OFFSET = 170;
const LABELS_GAP = 20;
let widget;
let annotationHelper = null;
export class CustomLabelsFilter extends LabelsFilter {
  constructor() {
    super();
  }
  labelInfo(node) {
    if (node.getName() === "casing")
      return null;
    if (node.getName() === "perforation") {
      const entity = node.getGeometryData();
      let range;
      if (Array.isArray(entity)) {
        range = entity[entity.length - 1];
      } else {
        range = entity;
      }
      return "perforation @ " + range["depth"]["from"] + " - " + range["depth"]["to"];
    }
    return ComponentUtils.getDescriptionString(node.getDescription()) || node.getName();
  }
}
obfuscate(CustomLabelsFilter);
function createScene(canvas) {
  const wellBoreData = new WellBoreData(data);
  widget = new CompositeSchematicsWidget({
    "annotationssizes": {
      "west": WEST_AXIS_WIDTH
    },
    "gap": {
      "left": { "size": SCHEMATICS_OFFSET + "px" },
      "right": { "size": SCHEMATICS_OFFSET - 2 * LABELS_GAP + "px" }
    },
    "labeling": {
      "labelsfilter": new CustomLabelsFilter(),
      "defaultlocation": LocationType.Left
    },
    "trackwidthstrategy": new FixedTrackWidthStrategy(SCHEMATICS_WIDTH),
    "alignment": Alignment.Left,
    "data": {
      "elements": wellBoreData
    }
  });
  annotationHelper = new AnnotationHelper(widget);
  const plot = new Plot({
    "canvaselement": canvas,
    "root": widget
  });
  createDefaultAnnotations(data, annotationHelper);
  return {
    "annotationHelper": annotationHelper,
    "plot": plot
  };
}
function createDefaultAnnotations(data2, annotationHelper2) {
  data2.forEach((element) => {
    annotationHelper2.addAnnotation(element, {
      "left": {
        "x": SCHEMATICS_OFFSET - LABELS_GAP
      },
      "right": {
        "x": SCHEMATICS_OFFSET + SCHEMATICS_WIDTH + LABELS_GAP
      }
    });
  });
}
function switchViewMode(compressed, annotationHelper2) {
  if (widget && annotationHelper2) {
    annotationHelper2.getAnnotationTool().getManipulatorLayer().clearChildren();
    widget.setViewMode(compressed ? ViewMode.Compressed : ViewMode.Regular);
    annotationHelper2.updateAnnotations();
  }
}
function onResize(annotationHelper2) {
  if (annotationHelper2) {
    annotationHelper2.getAnnotationTool().getManipulatorLayer().clearChildren();
    annotationHelper2.updateAnnotations();
  }
}
function printToPdf(annotationHelper2) {
  if (widget && annotationHelper2) {
    annotationHelper2.getAnnotationTool().getManipulatorLayer().clearChildren();
    const annotationsBounds = annotationHelper2.getAnnotationsBounds();
    const options = {
      "printsettings": {
        "keepaspectratio": true,
        "scaling": ScalingOptions.FitWidth
      }
    };
    if (annotationsBounds != null) {
      annotationsBounds.setWidth(annotationsBounds.getWidth() + LABELS_GAP);
      deepMergeObject({ "modellimits": annotationsBounds }, options);
    }
    widget.exportToPdf(options);
  }
}
function setAnnotationEditMode(editMode, annotationHelper2) {
  if (annotationHelper2) {
    annotationHelper2.setAnnotationEditMode(editMode);
  }
}
function removeActiveAnnotation(annotationHelper2) {
  if (annotationHelper2) {
    annotationHelper2.removeActiveAnnotation();
  }
}
function hasSelection(annotationHelper2) {
  return annotationHelper2 != null ? annotationHelper2.hasSelection() : false;
}
export { createScene, hasSelection, onResize, printToPdf, removeActiveAnnotation, setAnnotationEditMode, switchViewMode };

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