A device cache helps to separate the rendering process from the physical device and improve application performance. This tutorial demonstrates how to define a cache strategy to pre-render a group's children in a set of tiles.
# Using Caches
Setting a cache on the group redirects the rendering after an invalidate to the view cache tiles. Any subsequent renders will be from the view cache tiles and until invalidate is called. Rectangles are added to the group to show approximate tile locations. Caches allow rendering intensive groups in a quickly.
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rectangle } from "@int/geotoolkit/scene/shapes/Rectangle.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
function createScene(canvas) {
const rectangles = [];
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
rectangles.push(new Rectangle({
"left": i * 256,
"top": j * 256,
"width": 256,
"height": 256,
"fillstyle": KnownColors.Orange,
"linestyle": {
"pixelsnapmode": true
}
}));
}
}
return new Plot({
"canvaselement": canvas,
"root": new Group().setModelLimits(new Rect(0, 0, 900, 900)).addChild(rectangles)
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));
# Example of Caches in Action
The left and right plots are the same, except the right plot has a ViewCache. These plots are artificially made heavy with 40000 rectangles. Click and drag to pan around the plots. It is clear that Groups with ViewCache have better rendering performance than heavy Groups.
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { AnnotatedWidget } from "@int/geotoolkit/widgets/AnnotatedWidget.ts";
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { ViewCache } from "@int/geotoolkit/scene/ViewCache.ts";
import { Text } from "@int/geotoolkit/scene/shapes/Text.ts";
import { Rectangle } from "@int/geotoolkit/scene/shapes/Rectangle.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
const w = 100, h = 100, count = 30, maxShapes = 4e4;
function createModel(isUseCache) {
const rectangles = [];
for (let i = 0; i < maxShapes; i++) {
rectangles.push(new Rectangle({
"left": Math.ceil(w * count * Math.random()),
"top": Math.ceil(h * count * Math.random()),
"width": 90,
"height": 90,
"fillstyle": "#33553333",
"linestyle": {
"color": "black",
"pixelsnapmode": true
}
}));
}
return new Group().setModelLimits(new Rect(0, 0, w * count, h * count)).setCache(isUseCache ? new ViewCache() : null).addChild(rectangles);
}
function createPlot(canvas, isUseCache) {
const annotatedWidget = new AnnotatedWidget({
"model": createModel(isUseCache),
"annotationssizes": {
"north": 50,
"east": 0,
"south": 0,
"west": 0
},
"north": [
new Text({
"text": isUseCache ? "With View Cache" : "Without View Cache",
"ax": 0.5,
"ay": 0.5,
"textstyle": {
"color": "#757575",
"font": "18px Roboto"
}
})
]
}).scaleModel(1.5, 1.5);
return new Plot({
"canvaselement": canvas,
"root": annotatedWidget
});
}
function createScene(canvasWithoutCache, canvasWithCache) {
return [
createPlot(canvasWithoutCache, false),
createPlot(canvasWithCache, true)
];
}
export { createScene };
createScene(document.querySelector('[ref="plot1"]'), document.querySelector('[ref="plot2"]'));