Add types and comments to make combined image+text decluttering clearer
This commit is contained in:
@@ -100,15 +100,15 @@ class VectorContext {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../style/Image.js").default} imageStyle Image style.
|
* @param {import("../style/Image.js").default} imageStyle Image style.
|
||||||
* @param {Object=} opt_sharedData Shared data for combined decluttering with a text style.
|
* @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with a text style.
|
||||||
*/
|
*/
|
||||||
setImageStyle(imageStyle, opt_sharedData) {}
|
setImageStyle(imageStyle, opt_declutterImageWithText) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../style/Text.js").default} textStyle Text style.
|
* @param {import("../style/Text.js").default} textStyle Text style.
|
||||||
* @param {Object=} opt_sharedData Shared data for combined decluttering with an image style.
|
* @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with an image style.
|
||||||
*/
|
*/
|
||||||
setTextStyle(textStyle, opt_sharedData) {}
|
setTextStyle(textStyle, opt_declutterImageWithText) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default VectorContext;
|
export default VectorContext;
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ import {toString} from '../transform.js';
|
|||||||
* @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).
|
* @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object<number, import("./canvas/Executor.js").ReplayImageOrLabelArgs>} DeclutterImageWithText
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ import {transform2D} from '../../geom/flat/transform.js';
|
|||||||
* @property {import("../../transform.js").Transform} canvasTransform
|
* @property {import("../../transform.js").Transform} canvasTransform
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{0: CanvasRenderingContext2D, 1: number, 2: import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement, 3: ImageOrLabelDimensions, 4: number, 5: Array<*>, 6: Array<*>}} ReplayImageOrLabelArgs
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import("../../extent.js").Extent}
|
* @type {import("../../extent.js").Extent}
|
||||||
*/
|
*/
|
||||||
@@ -64,12 +68,11 @@ const p3 = [];
|
|||||||
const p4 = [];
|
const p4 = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array<*>} replayImageOrLabelArgs Arguments to replayImageOrLabel
|
* @param {ReplayImageOrLabelArgs} replayImageOrLabelArgs Arguments to replayImageOrLabel
|
||||||
* @return {BBox} Declutter bbox.
|
* @return {BBox} Declutter bbox.
|
||||||
*/
|
*/
|
||||||
function getDeclutterBox(replayImageOrLabelArgs) {
|
function getDeclutterBox(replayImageOrLabelArgs) {
|
||||||
return /** @type {ImageOrLabelDimensions} */ (replayImageOrLabelArgs[3])
|
return replayImageOrLabelArgs[3].declutterBox;
|
||||||
.declutterBox;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Executor {
|
class Executor {
|
||||||
@@ -724,7 +727,7 @@ class Executor {
|
|||||||
let rotation = /** @type {number} */ (instruction[11]);
|
let rotation = /** @type {number} */ (instruction[11]);
|
||||||
const scale = /** @type {import("../../size.js").Size} */ (instruction[12]);
|
const scale = /** @type {import("../../size.js").Size} */ (instruction[12]);
|
||||||
let width = /** @type {number} */ (instruction[13]);
|
let width = /** @type {number} */ (instruction[13]);
|
||||||
const sharedData = instruction[14];
|
const declutterImageWithText = /** @type {import("../canvas.js").DeclutterImageWithText} */ (instruction[14]);
|
||||||
|
|
||||||
if (!image && instruction.length >= 19) {
|
if (!image && instruction.length >= 19) {
|
||||||
// create label images
|
// create label images
|
||||||
@@ -801,6 +804,7 @@ class Executor {
|
|||||||
backgroundFill || backgroundStroke,
|
backgroundFill || backgroundStroke,
|
||||||
feature
|
feature
|
||||||
);
|
);
|
||||||
|
/** @type {ReplayImageOrLabelArgs} */
|
||||||
const args = [
|
const args = [
|
||||||
context,
|
context,
|
||||||
contextScale,
|
contextScale,
|
||||||
@@ -816,13 +820,15 @@ class Executor {
|
|||||||
];
|
];
|
||||||
let imageArgs;
|
let imageArgs;
|
||||||
let imageDeclutterBox;
|
let imageDeclutterBox;
|
||||||
if (opt_declutterTree && sharedData) {
|
if (opt_declutterTree && declutterImageWithText) {
|
||||||
if (!sharedData[d]) {
|
if (!declutterImageWithText[d]) {
|
||||||
sharedData[d] = args;
|
// We now have the image for an image+text combination.
|
||||||
|
declutterImageWithText[d] = args;
|
||||||
|
// Don't render anything for now, wait for the text.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
imageArgs = sharedData[d];
|
imageArgs = declutterImageWithText[d];
|
||||||
delete sharedData[d];
|
delete declutterImageWithText[d];
|
||||||
imageDeclutterBox = getDeclutterBox(imageArgs);
|
imageDeclutterBox = getDeclutterBox(imageArgs);
|
||||||
if (opt_declutterTree.collides(imageDeclutterBox)) {
|
if (opt_declutterTree.collides(imageDeclutterBox)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -835,9 +841,11 @@ class Executor {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (imageArgs) {
|
if (imageArgs) {
|
||||||
|
// We now have image and text for an image+text combination.
|
||||||
if (opt_declutterTree) {
|
if (opt_declutterTree) {
|
||||||
opt_declutterTree.insert(imageDeclutterBox);
|
opt_declutterTree.insert(imageDeclutterBox);
|
||||||
}
|
}
|
||||||
|
// Render the image before we render the text.
|
||||||
this.replayImageOrLabel_.apply(this, imageArgs);
|
this.replayImageOrLabel_.apply(this, imageArgs);
|
||||||
}
|
}
|
||||||
if (opt_declutterTree) {
|
if (opt_declutterTree) {
|
||||||
@@ -902,6 +910,7 @@ class Executor {
|
|||||||
viewRotationFromTransform ? 0 : this.viewRotation_
|
viewRotationFromTransform ? 0 : this.viewRotation_
|
||||||
);
|
);
|
||||||
drawChars: if (parts) {
|
drawChars: if (parts) {
|
||||||
|
/** @type {Array<ReplayImageOrLabelArgs>} */
|
||||||
const replayImageOrLabelArgs = [];
|
const replayImageOrLabelArgs = [];
|
||||||
let c, cc, chars, label, part;
|
let c, cc, chars, label, part;
|
||||||
if (strokeKey) {
|
if (strokeKey) {
|
||||||
|
|||||||
@@ -95,9 +95,9 @@ class CanvasImageBuilder extends CanvasBuilder {
|
|||||||
/**
|
/**
|
||||||
* Data shared with a text builder for combined decluttering.
|
* Data shared with a text builder for combined decluttering.
|
||||||
* @private
|
* @private
|
||||||
* @type {Object}
|
* @type {import("../canvas.js").DeclutterImageWithText}
|
||||||
*/
|
*/
|
||||||
this.sharedData_ = undefined;
|
this.declutterImageWithText_ = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,7 +132,7 @@ class CanvasImageBuilder extends CanvasBuilder {
|
|||||||
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
|
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
|
||||||
],
|
],
|
||||||
Math.ceil(this.width_ * this.imagePixelRatio_),
|
Math.ceil(this.width_ * this.imagePixelRatio_),
|
||||||
this.sharedData_,
|
this.declutterImageWithText_,
|
||||||
]);
|
]);
|
||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
CanvasInstruction.DRAW_IMAGE,
|
CanvasInstruction.DRAW_IMAGE,
|
||||||
@@ -150,7 +150,7 @@ class CanvasImageBuilder extends CanvasBuilder {
|
|||||||
this.rotation_,
|
this.rotation_,
|
||||||
this.scale_,
|
this.scale_,
|
||||||
this.width_,
|
this.width_,
|
||||||
this.sharedData_,
|
this.declutterImageWithText_,
|
||||||
]);
|
]);
|
||||||
this.endGeometry(feature);
|
this.endGeometry(feature);
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ class CanvasImageBuilder extends CanvasBuilder {
|
|||||||
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
|
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
|
||||||
],
|
],
|
||||||
Math.ceil(this.width_ * this.imagePixelRatio_),
|
Math.ceil(this.width_ * this.imagePixelRatio_),
|
||||||
this.sharedData_,
|
this.declutterImageWithText_,
|
||||||
]);
|
]);
|
||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
CanvasInstruction.DRAW_IMAGE,
|
CanvasInstruction.DRAW_IMAGE,
|
||||||
@@ -205,7 +205,7 @@ class CanvasImageBuilder extends CanvasBuilder {
|
|||||||
this.rotation_,
|
this.rotation_,
|
||||||
this.scale_,
|
this.scale_,
|
||||||
this.width_,
|
this.width_,
|
||||||
this.sharedData_,
|
this.declutterImageWithText_,
|
||||||
]);
|
]);
|
||||||
this.endGeometry(feature);
|
this.endGeometry(feature);
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,7 @@ class CanvasImageBuilder extends CanvasBuilder {
|
|||||||
this.rotation_ = imageStyle.getRotation();
|
this.rotation_ = imageStyle.getRotation();
|
||||||
this.scale_ = imageStyle.getScaleArray();
|
this.scale_ = imageStyle.getScaleArray();
|
||||||
this.width_ = size[0];
|
this.width_ = size[0];
|
||||||
this.sharedData_ = opt_sharedData;
|
this.declutterImageWithText_ = opt_sharedData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,9 +142,9 @@ class CanvasTextBuilder extends CanvasBuilder {
|
|||||||
/**
|
/**
|
||||||
* Data shared with an image builder for combined decluttering.
|
* Data shared with an image builder for combined decluttering.
|
||||||
* @private
|
* @private
|
||||||
* @type {Object}
|
* @type {import("../canvas.js").DeclutterImageWithText}
|
||||||
*/
|
*/
|
||||||
this.sharedData_ = undefined;
|
this.declutterImageWithText_ = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -335,7 +335,7 @@ class CanvasTextBuilder extends CanvasBuilder {
|
|||||||
this.textRotation_,
|
this.textRotation_,
|
||||||
[1, 1],
|
[1, 1],
|
||||||
NaN,
|
NaN,
|
||||||
this.sharedData_,
|
this.declutterImageWithText_,
|
||||||
padding == defaultPadding
|
padding == defaultPadding
|
||||||
? defaultPadding
|
? defaultPadding
|
||||||
: padding.map(function (p) {
|
: padding.map(function (p) {
|
||||||
@@ -367,7 +367,7 @@ class CanvasTextBuilder extends CanvasBuilder {
|
|||||||
this.textRotation_,
|
this.textRotation_,
|
||||||
[scale, scale],
|
[scale, scale],
|
||||||
NaN,
|
NaN,
|
||||||
this.sharedData_,
|
this.declutterImageWithText_,
|
||||||
padding,
|
padding,
|
||||||
!!textState.backgroundFill,
|
!!textState.backgroundFill,
|
||||||
!!textState.backgroundStroke,
|
!!textState.backgroundStroke,
|
||||||
@@ -586,7 +586,7 @@ class CanvasTextBuilder extends CanvasBuilder {
|
|||||||
: '|' + getUid(fillState.fillStyle)
|
: '|' + getUid(fillState.fillStyle)
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
this.sharedData_ = opt_sharedData;
|
this.declutterImageWithText_ = opt_sharedData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -346,10 +346,11 @@ function renderPointGeometry(
|
|||||||
) {
|
) {
|
||||||
const imageStyle = style.getImage();
|
const imageStyle = style.getImage();
|
||||||
const textStyle = style.getText();
|
const textStyle = style.getText();
|
||||||
let sharedData;
|
/** @type {import("../render/canvas.js").DeclutterImageWithText} */
|
||||||
|
let declutterImageWithText;
|
||||||
if (opt_declutterBuilderGroup) {
|
if (opt_declutterBuilderGroup) {
|
||||||
builderGroup = opt_declutterBuilderGroup;
|
builderGroup = opt_declutterBuilderGroup;
|
||||||
sharedData =
|
declutterImageWithText =
|
||||||
imageStyle && textStyle && textStyle.getText() ? {} : undefined;
|
imageStyle && textStyle && textStyle.getText() ? {} : undefined;
|
||||||
}
|
}
|
||||||
if (imageStyle) {
|
if (imageStyle) {
|
||||||
@@ -360,7 +361,7 @@ function renderPointGeometry(
|
|||||||
style.getZIndex(),
|
style.getZIndex(),
|
||||||
BuilderType.IMAGE
|
BuilderType.IMAGE
|
||||||
);
|
);
|
||||||
imageReplay.setImageStyle(imageStyle, sharedData);
|
imageReplay.setImageStyle(imageStyle, declutterImageWithText);
|
||||||
imageReplay.drawPoint(geometry, feature);
|
imageReplay.drawPoint(geometry, feature);
|
||||||
}
|
}
|
||||||
if (textStyle && textStyle.getText()) {
|
if (textStyle && textStyle.getText()) {
|
||||||
@@ -368,7 +369,7 @@ function renderPointGeometry(
|
|||||||
style.getZIndex(),
|
style.getZIndex(),
|
||||||
BuilderType.TEXT
|
BuilderType.TEXT
|
||||||
);
|
);
|
||||||
textReplay.setTextStyle(textStyle, sharedData);
|
textReplay.setTextStyle(textStyle, declutterImageWithText);
|
||||||
textReplay.drawText(geometry, feature);
|
textReplay.drawText(geometry, feature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -389,10 +390,11 @@ function renderMultiPointGeometry(
|
|||||||
) {
|
) {
|
||||||
const imageStyle = style.getImage();
|
const imageStyle = style.getImage();
|
||||||
const textStyle = style.getText();
|
const textStyle = style.getText();
|
||||||
let sharedData;
|
/** @type {import("../render/canvas.js").DeclutterImageWithText} */
|
||||||
|
let declutterImageWithText;
|
||||||
if (opt_declutterBuilderGroup) {
|
if (opt_declutterBuilderGroup) {
|
||||||
builderGroup = opt_declutterBuilderGroup;
|
builderGroup = opt_declutterBuilderGroup;
|
||||||
sharedData =
|
declutterImageWithText =
|
||||||
imageStyle && textStyle && textStyle.getText() ? {} : undefined;
|
imageStyle && textStyle && textStyle.getText() ? {} : undefined;
|
||||||
}
|
}
|
||||||
if (imageStyle) {
|
if (imageStyle) {
|
||||||
@@ -403,7 +405,7 @@ function renderMultiPointGeometry(
|
|||||||
style.getZIndex(),
|
style.getZIndex(),
|
||||||
BuilderType.IMAGE
|
BuilderType.IMAGE
|
||||||
);
|
);
|
||||||
imageReplay.setImageStyle(imageStyle, sharedData);
|
imageReplay.setImageStyle(imageStyle, declutterImageWithText);
|
||||||
imageReplay.drawMultiPoint(geometry, feature);
|
imageReplay.drawMultiPoint(geometry, feature);
|
||||||
}
|
}
|
||||||
if (textStyle && textStyle.getText()) {
|
if (textStyle && textStyle.getText()) {
|
||||||
@@ -411,7 +413,7 @@ function renderMultiPointGeometry(
|
|||||||
style.getZIndex(),
|
style.getZIndex(),
|
||||||
BuilderType.TEXT
|
BuilderType.TEXT
|
||||||
);
|
);
|
||||||
textReplay.setTextStyle(textStyle, sharedData);
|
textReplay.setTextStyle(textStyle, declutterImageWithText);
|
||||||
textReplay.drawText(geometry, feature);
|
textReplay.drawText(geometry, feature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user