Last updated

Custom Shape

One of the key strengths of GeoToolkitJS is that the user can create new industry specific shapes and is not limited to INT pre-built shapes. This capability makes the GeoToolkit very extensible.
The following tutorial shows how to create a custom shape for a well by extending the base Shape class.

To implement a custom shape, perform these steps:

  • Extend base class. It can be Node or Shape. Shape is chosen here because it provides methods to specify attributes.
  • Override method checkCollision to test if the shape is in the specified area.
  • Override method render to render the shape into the RenderingContext.
  • Call geotoolkit/lib/obfuscate to map obfuscation version of the base class.
import { Shape } from "@int/geotoolkit/scene/shapes/Shape.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { obfuscate } from "@int/geotoolkit/lib.js";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
class CustomSymbol extends Shape {
  constructor(rect) {
    super();
    this.rect = rect;
    this.bounds = new Rect(rect);
  }
  getBounds() {
    return this.bounds;
  }
  checkCollision(context) {
    return this.getVisible() === true && CustomSymbol.intersectsBounds(
      this.getBounds(),
      this.getLocalTransform(),
      context.getModelRect()
    );
  }
  render(context) {
    const x = this.rect.getX(), y = this.rect.getY(), w = this.rect.getWidth(), h = this.rect.getHeight();
    const radiusX = w * (3 / 5) / 2;
    const radiusY = h * (3 / 5) / 2;
    const lc = this.getWorldTransform() != null ? context.pushTransformation(this.getWorldTransform()) : context;
    lc.setCurrentNode(this);
    lc.setLineStyle(this.getLineStyle()).drawLine(x, y, x + w, y + h).drawLine(x, y + h, x + w, y).drawLine(x, y + h / 2, x + w, y + h / 2).drawLine(x + w / 2, y, x + w / 2, y + h);
    lc.drawLine(x, y, x + w, y + h).drawLine(x, y + h, x + w, y).drawLine(x, y + h / 2, x + x, y + h / 2).drawLine(x + w / 2, y, x + w / 2, y + h);
    lc.setFillStyle(this.getFillStyle()).drawEllipse(x + w / 2 - radiusX, y + h / 2 - radiusY, radiusX * 2, radiusY * 2);
  }
}
obfuscate(CustomSymbol);
function createScene(canvas) {
  const symbol = new CustomSymbol(new Rect(50, 50, 150, 150)).setLineStyle({
    "color": KnownColors.Orange,
    "width": 2
  }).setFillStyle("white");
  const group = new Group().setBounds(new Rect(0, 0, 200, 200)).setModelLimits(new Rect(0, 0, 200, 200)).addChild(symbol);
  return new Plot({
    "canvaselement": canvas,
    "root": group
  });
}
export { createScene };

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