A Symbol in CarnacJS is a light weight shape that inherits from AnchoredShape and it is drawn by SymbolPainters. CarnacJS has a catalog of pre-built SymbolPainters which consists of various geometrical shapes. It also has a domain specific or standard Oil&Gas SymbolPainters.
This tutorial demonstrates how to create different types of Symbols using the built in SymbolPainters and also shows how easy it is to write a Custom Painter.
# Symbol Basics
Symbols are shapes defined by a Symbol Painter. They are anchored shapes defined by coordinates, width and height, an anchor, and a symbol painter.
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { TrianglePainter } from "@int/geotoolkit/scene/shapes/painters/TrianglePainter.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
function createScene(canvas) {
const triangle = new SymbolShape({
"ax": 100,
"ay": 100,
"width": 30,
"height": 60,
"alignment": AnchorType.Center,
"sizeisindevicespace": false,
"painter": TrianglePainter,
"linestyle": {
"color": KnownColors.DarkBlue,
"width": 2
},
"fillstyle": KnownColors.Orange
});
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild(triangle)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Painters
A catalog of symbol painters included with GeoToolkitJS. Different positions of anchor point relative to symbol shape are demonstrated. Position of anchor is marked with small red square.
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { CirclePainter } from "@int/geotoolkit/scene/shapes/painters/CirclePainter.ts";
import { CrossPainter } from "@int/geotoolkit/scene/shapes/painters/CrossPainter.ts";
import { DiamondPainter } from "@int/geotoolkit/scene/shapes/painters/DiamondPainter.ts";
import { PlusPainter } from "@int/geotoolkit/scene/shapes/painters/PlusPainter.ts";
import { SquarePainter } from "@int/geotoolkit/scene/shapes/painters/SquarePainter.ts";
import { StarPainter } from "@int/geotoolkit/scene/shapes/painters/StarPainter.ts";
import { TrianglePainter } from "@int/geotoolkit/scene/shapes/painters/TrianglePainter.ts";
import { PlusBarPainter } from "@int/geotoolkit/scene/shapes/painters/PlusBarPainter.ts";
import { Star5Painter } from "@int/geotoolkit/scene/shapes/painters/Star5Painter.ts";
import { FillStyle } from "@int/geotoolkit/attributes/FillStyle.ts";
import { LineStyle } from "@int/geotoolkit/attributes/LineStyle.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
function makeAnchorShape(x, y) {
return new SymbolShape({
"ax": x,
"ay": y,
"width": 7,
"height": 7,
"painter": SquarePainter,
"fillstyle": "red"
});
}
function createScene(canvas) {
const shapes = [];
shapes.push(new SymbolShape(125, 75, 50, 50, AnchorType.RightBottom, false, CirclePainter));
shapes.push(new SymbolShape(200, 75, 50, 50, AnchorType.BottomCenter, false, CrossPainter));
shapes.push(new SymbolShape(275, 75, 50, 50, AnchorType.LeftBottom, false, DiamondPainter));
shapes.push(new SymbolShape(125, 150, 50, 50, AnchorType.RightCenter, false, PlusPainter));
shapes.push(new SymbolShape(200, 150, 50, 50, AnchorType.Center, false, SquarePainter));
shapes.push(new SymbolShape(275, 150, 50, 50, AnchorType.LeftCenter, false, StarPainter));
shapes.push(new SymbolShape(128, 225, 50, 50, AnchorType.RightTop, false, TrianglePainter));
shapes.push(new SymbolShape(200, 225, 50, 50, AnchorType.TopCenter, false, PlusBarPainter));
shapes.push(new SymbolShape(275, 225, 50, 50, AnchorType.LeftTop, false, Star5Painter));
const fillStyle = new FillStyle(KnownColors.Orange);
const lineStyle = new LineStyle(KnownColors.DarkBlue, 2);
for (const shape in shapes) {
shapes[shape].setFillStyle(fillStyle).setLineStyle(lineStyle);
}
const anchors = [];
anchors.push(makeAnchorShape(125, 75));
anchors.push(makeAnchorShape(200, 75));
anchors.push(makeAnchorShape(275, 75));
anchors.push(makeAnchorShape(125, 150));
anchors.push(makeAnchorShape(200, 150));
anchors.push(makeAnchorShape(275, 150));
anchors.push(makeAnchorShape(125, 225));
anchors.push(makeAnchorShape(200, 225));
anchors.push(makeAnchorShape(275, 225));
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild(shapes).addChild(anchors)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# O&G Painters
A catalog of Oil&Gas dedicated symbolpainters included with GeoToolkitJS.
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { LocationPermit } from "@int/geotoolkit/scene/shapes/painters/oilandgas/LocationPermit.ts";
import { LocationPermitExpired } from "@int/geotoolkit/scene/shapes/painters/oilandgas/LocationPermitExpired.ts";
import { Dry } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Dry.ts";
import { Injection } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Injection.ts";
import { Lost } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Lost.ts";
import { Unknown } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Unknown.ts";
import { ShowGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/ShowGas.ts";
import { DryShowGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/DryShowGas.ts";
import { GasShowOil } from "@int/geotoolkit/scene/shapes/painters/oilandgas/GasShowOil.ts";
import { DryShowOil } from "@int/geotoolkit/scene/shapes/painters/oilandgas/DryShowOil.ts";
import { DryShowOilGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/DryShowOilGas.ts";
import { ShowOil } from "@int/geotoolkit/scene/shapes/painters/oilandgas/ShowOil.ts";
import { Gas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Gas.ts";
import { Oil } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Oil.ts";
import { OilGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/OilGas.ts";
import { OilShowGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/OilShowGas.ts";
import { ShowOilGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/ShowOilGas.ts";
import { PluggedGasShowOil } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedGasShowOil.ts";
import { PluggedGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedGas.ts";
import { PluggedOil } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedOil.ts";
import { PluggedOilGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedOilGas.ts";
import { PluggedOilShowGas } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedOilShowGas.ts";
import { PluggedInjection } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedInjection.ts";
import { Observation } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Observation.ts";
import { Brine } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Brine.ts";
import { WaterSupply } from "@int/geotoolkit/scene/shapes/painters/oilandgas/WaterSupply.ts";
import { PluggedBrine } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedBrine.ts";
import { PluggedWaterSupply } from "@int/geotoolkit/scene/shapes/painters/oilandgas/PluggedWaterSupply.ts";
import { Water } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Water.ts";
import { FillStyle } from "@int/geotoolkit/attributes/FillStyle.ts";
import { LineStyle } from "@int/geotoolkit/attributes/LineStyle.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
function createScene(canvas) {
const shapes = [];
shapes.push(new SymbolShape(57, 100, 50, 50, AnchorType.Center, false, LocationPermit));
shapes.push(new SymbolShape(114, 100, 50, 50, AnchorType.Center, false, LocationPermitExpired));
shapes.push(new SymbolShape(171, 100, 50, 50, AnchorType.Center, false, Dry));
shapes.push(new SymbolShape(229, 100, 50, 50, AnchorType.Center, false, Injection));
shapes.push(new SymbolShape(286, 100, 50, 50, AnchorType.Center, false, Lost));
shapes.push(new SymbolShape(343, 100, 50, 50, AnchorType.Center, false, Unknown));
shapes.push(new SymbolShape(57, 200, 50, 50, AnchorType.Center, false, ShowGas));
shapes.push(new SymbolShape(114, 200, 50, 50, AnchorType.Center, false, DryShowGas));
shapes.push(new SymbolShape(171, 200, 50, 50, AnchorType.Center, false, GasShowOil));
shapes.push(new SymbolShape(229, 200, 50, 50, AnchorType.Center, false, DryShowOil));
shapes.push(new SymbolShape(286, 200, 50, 50, AnchorType.Center, false, DryShowOilGas));
shapes.push(new SymbolShape(343, 200, 50, 50, AnchorType.Center, false, ShowOil));
shapes.push(new SymbolShape(57, 300, 50, 50, AnchorType.Center, false, Gas));
shapes.push(new SymbolShape(114, 300, 50, 50, AnchorType.Center, false, Oil));
shapes.push(new SymbolShape(171, 300, 50, 50, AnchorType.Center, false, OilGas));
shapes.push(new SymbolShape(229, 300, 50, 50, AnchorType.Center, false, OilShowGas));
shapes.push(new SymbolShape(286, 300, 50, 50, AnchorType.Center, false, ShowOilGas));
shapes.push(new SymbolShape(343, 300, 50, 50, AnchorType.Center, false, PluggedGasShowOil));
shapes.push(new SymbolShape(57, 400, 50, 50, AnchorType.Center, false, PluggedGas));
shapes.push(new SymbolShape(114, 400, 50, 50, AnchorType.Center, false, PluggedOil));
shapes.push(new SymbolShape(171, 400, 50, 50, AnchorType.Center, false, PluggedOilGas));
shapes.push(new SymbolShape(229, 400, 50, 50, AnchorType.Center, false, PluggedOilShowGas));
shapes.push(new SymbolShape(286, 400, 50, 50, AnchorType.Center, false, PluggedInjection));
shapes.push(new SymbolShape(343, 400, 50, 50, AnchorType.Center, false, Observation));
shapes.push(new SymbolShape(57, 500, 50, 50, AnchorType.Center, false, Brine));
shapes.push(new SymbolShape(114, 500, 50, 50, AnchorType.Center, false, WaterSupply));
shapes.push(new SymbolShape(171, 500, 50, 50, AnchorType.Center, false, PluggedBrine));
shapes.push(new SymbolShape(229, 500, 50, 50, AnchorType.Center, false, PluggedWaterSupply));
shapes.push(new SymbolShape(286, 500, 50, 50, AnchorType.Center, false, Water));
const fillStyle = new FillStyle(KnownColors.Orange);
const lineStyle = new LineStyle(KnownColors.DarkBlue, 2);
for (const shape in shapes) {
shapes[shape].setFillStyle(fillStyle).setLineStyle(lineStyle);
}
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild(shapes)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Geometry Painter
A geometry symbol painter can be used to reuse simple geometry as symbol. For example to create composite symbol based on other symbols.
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { Text } from "@int/geotoolkit/scene/shapes/Text.ts";
import { GeometryPainter } from "@int/geotoolkit/scene/shapes/painters/GeometryPainter.ts";
import { Dry } from "@int/geotoolkit/scene/shapes/painters/oilandgas/Dry.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
function createScene(canvas) {
const symbol = new SymbolShape({
"ax": 100,
"ay": 100,
"width": 60,
"height": 60,
"alignment": AnchorType.Center,
"painter": new GeometryPainter({
"geometry": new Group().setBounds(new Rect(0, 0, 60, 60)).addChild([
new SymbolShape({
"ax": 30,
"ay": 30,
"width": 60,
"height": 60,
"alignment": AnchorType.Center,
"painter": Dry,
"linestyle": KnownColors.Green
}),
new Text({
"ax": 60,
"ay": 0,
"alignment": AnchorType.RightTop,
"sizeisindevicespace": true,
"text": "NE",
"textstyle": {
"color": KnownColors.Blue,
"font": "14px sans-serif"
}
})
])
})
});
symbol.setCss({
"css": [
".geotoolkit.scene.shapes.SymbolShape {",
" linestyle: " + KnownColors.DarkBlue + ";",
"}",
".geotoolkit.scene.shapes.Text {",
" textstyle-color: " + KnownColors.Green + ";",
"}"
].join("")
});
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild(symbol)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Custom Painter
A custom symbol painter can be used to create your own symbols. To create a custom painter, define a function that accepts a symbol, bounding box, and rendering context.
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
function PluggedBrineWellSymbolPainter(symbol, bbox, context) {
context.setFillStyle(symbol.getFillStyle());
context.setLineStyle(symbol.getLineStyle());
context.drawLine(bbox.getLeft(), bbox.getTop(), bbox.getRight(), bbox.getBottom());
context.drawEllipse(bbox.getLeft(), bbox.getTop(), bbox.getWidth(), bbox.getHeight());
context.drawLine(bbox.getLeft(), bbox.getBottom(), bbox.getRight(), bbox.getTop());
context.fillPath();
context.stroke();
}
function createScene(canvas) {
const symbol = new SymbolShape(100, 100, 60, 60, AnchorType.Center, false, PluggedBrineWellSymbolPainter).setFillStyle(KnownColors.Orange).setLineStyle({
"color": KnownColors.DarkBlue,
"width": 2
});
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild(symbol)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Font Painter
A font symbol painter can be used to create symbols from font. To create a font painter, specify the font location, font family(must match with font name) and string that contains symbols codes.
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { FontPainter } from "@int/geotoolkit/scene/shapes/painters/FontPainter.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
import font from "/src/assets/fonts/Noto Sans Bold.ttf?import";
function createScene(canvas) {
const symbol = new SymbolShape({
ax: 50,
ay: 80,
width: 80,
height: 80,
preserveaspectratio: true,
alignment: AnchorType.Center,
painter: new FontPainter(font, '"Noto Sans Bold"', "\xA9"),
fillstyle: KnownColors.Orange,
linestyle: {
"color": KnownColors.DarkBlue,
"width": 2
}
});
const symbol1 = new SymbolShape({
ax: 150,
ay: 80,
width: 80,
height: 80,
preserveaspectratio: true,
alignment: AnchorType.Center,
painter: new FontPainter(font, '"Noto Sans Bold"', "\u2117"),
fillstyle: KnownColors.Orange,
linestyle: {
"color": KnownColors.DarkBlue,
"width": 2
}
});
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild([symbol, symbol1])
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# LineAndSymbol Painter
LineAndSymbol Painter is used specially for Line Chart to display Line and symbol. To create LineAndSymbol Painter, specify the painter to be displayed with Line.
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { LineAndSymbolPainter } from "@int/geotoolkit/scene/shapes/painters/LineAndSymbolPainter.ts";
import { Star5Painter } from "@int/geotoolkit/scene/shapes/painters/Star5Painter.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
function createScene(canvas) {
const symbol = new SymbolShape({
ax: 100,
ay: 100,
width: 150,
height: 150,
alignment: AnchorType.Center,
painter: new LineAndSymbolPainter(Star5Painter),
fillstyle: KnownColors.Orange,
linestyle: {
"color": KnownColors.DarkBlue,
"width": 2
}
});
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild(symbol)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Image Painter
A image symbol painter can be used to create symbols from image. To create a image painter, specify the url image.
import { SymbolShape } from "@int/geotoolkit/scene/shapes/SymbolShape.ts";
import { AnchorType } from "@int/geotoolkit/util/AnchorType.ts";
import { ImagePainter } from "@int/geotoolkit/scene/shapes/painters/ImagePainter.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import image from "/src/assets/images/apple.png?import";
function createScene(canvas) {
const symbol = new SymbolShape({
ax: 80,
ay: 80,
width: 64,
height: 64,
preserveaspectratio: true,
alignment: AnchorType.Center,
painter: new ImagePainter(image)
});
return new Plot({
"canvaselement": canvas,
"root": new Group().addChild(symbol)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));