Prerender labels and cache them as images

This commit is contained in:
Andreas Hocevar
2017-08-31 16:19:33 +02:00
parent 5f2b729c74
commit 35bd92b713
15 changed files with 211 additions and 258 deletions

View File

@@ -20,10 +20,11 @@ goog.require('ol.transform');
* @param {number} tolerance Tolerance.
* @param {ol.Extent} maxExtent Maximum extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {boolean} overlaps The replay can have overlapping geometries.
* @struct
*/
ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) {
ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) {
ol.render.VectorContext.call(this);
/**
@@ -45,6 +46,11 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) {
*/
this.overlaps = overlaps;
/**
* @protected
* @type {number}
*/
this.pixelRatio = pixelRatio;
/**
* @protected
* @type {number}
@@ -342,7 +348,7 @@ ol.render.canvas.Replay.prototype.replay_ = function(
while (i < ii) {
var instruction = instructions[i];
var type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]);
var /** @type {ol.Feature|ol.render.Feature} */ feature, fill, stroke, text, x, y;
var /** @type {ol.Feature|ol.render.Feature} */ feature, x, y;
switch (type) {
case ol.render.canvas.Instruction.BEGIN_GEOMETRY:
feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]);
@@ -465,61 +471,6 @@ ol.render.canvas.Replay.prototype.replay_ = function(
}
++i;
break;
case ol.render.canvas.Instruction.DRAW_TEXT:
d = /** @type {number} */ (instruction[1]);
dd = /** @type {number} */ (instruction[2]);
text = /** @type {string} */ (instruction[3]);
var offsetX = /** @type {number} */ (instruction[4]) * pixelRatio;
var offsetY = /** @type {number} */ (instruction[5]) * pixelRatio;
rotation = /** @type {number} */ (instruction[6]);
scale = /** @type {number} */ (instruction[7]) * pixelRatio;
fill = /** @type {boolean} */ (instruction[8]);
stroke = /** @type {boolean} */ (instruction[9]);
rotateWithView = /** @type {boolean} */ (instruction[10]);
if (rotateWithView) {
rotation += viewRotation;
}
for (; d < dd; d += 2) {
x = pixelCoordinates[d] + offsetX;
y = pixelCoordinates[d + 1] + offsetY;
if (scale != 1 || rotation !== 0) {
ol.transform.compose(localTransform, x, y, scale, scale, rotation, -x, -y);
context.setTransform.apply(context, localTransform);
}
// Support multiple lines separated by \n
var lines = text.split('\n');
var numLines = lines.length;
var fontSize, lineY;
if (numLines > 1) {
// Estimate line height using width of capital M, and add padding
fontSize = Math.round(context.measureText('M').width * 1.5);
lineY = y - (((numLines - 1) / 2) * fontSize);
} else {
// No need to calculate line height/offset for a single line
fontSize = 0;
lineY = y;
}
for (var lineIndex = 0; lineIndex < numLines; lineIndex++) {
var line = lines[lineIndex];
if (stroke) {
context.strokeText(line, x, lineY);
}
if (fill) {
context.fillText(line, x, lineY);
}
// Move next line down by fontSize px
lineY = lineY + fontSize;
}
if (scale != 1 || rotation !== 0) {
context.setTransform.apply(context, resetTransform);
}
}
++i;
break;
case ol.render.canvas.Instruction.END_GEOMETRY:
if (featureCallback !== undefined) {
feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]);
@@ -610,12 +561,6 @@ ol.render.canvas.Replay.prototype.replay_ = function(
}
++i;
break;
case ol.render.canvas.Instruction.SET_TEXT_STYLE:
context.font = /** @type {string} */ (instruction[1]);
context.textAlign = /** @type {string} */ (instruction[2]);
context.textBaseline = /** @type {string} */ (instruction[3]);
++i;
break;
case ol.render.canvas.Instruction.STROKE:
if (batchSize) {
pendingStroke++;