Files
openlayers/src/ol/style/Image.js
VLCEK Martin e1593ce59d Support declutter mode for image styles
Allows to specify for each image style, whether the image
should be decluttered, always drawn but still serving as
obstacle, or drawn without being an obstacle for other
images/texts.

The layer must still have declutter = true set for this
property to have any effect.
2022-05-05 12:34:00 +02:00

298 lines
5.9 KiB
JavaScript

/**
* @module ol/style/Image
*/
import {abstract} from '../util.js';
import {toSize} from '../size.js';
/**
* @typedef {Object} Options
* @property {number} opacity Opacity.
* @property {boolean} rotateWithView If the image should get rotated with the view.
* @property {number} rotation Rotation.
* @property {number|import("../size.js").Size} scale Scale.
* @property {Array<number>} displacement Displacement.
* @property {"declutter"|"obstacle"|"none"|undefined} declutterMode Declutter mode: `declutter`, `obstacle`, 'none */
/**
* @classdesc
* A base class used for creating subclasses and not instantiated in
* apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and
* {@link module:ol/style/RegularShape~RegularShape}.
* @abstract
* @api
*/
class ImageStyle {
/**
* @param {Options} options Options.
*/
constructor(options) {
/**
* @private
* @type {number}
*/
this.opacity_ = options.opacity;
/**
* @private
* @type {boolean}
*/
this.rotateWithView_ = options.rotateWithView;
/**
* @private
* @type {number}
*/
this.rotation_ = options.rotation;
/**
* @private
* @type {number|import("../size.js").Size}
*/
this.scale_ = options.scale;
/**
* @private
* @type {import("../size.js").Size}
*/
this.scaleArray_ = toSize(options.scale);
/**
* @private
* @type {Array<number>}
*/
this.displacement_ = options.displacement;
/**
* @private
* @type {"declutter"|"obstacle"|"none"|undefined}
*/
this.declutterMode_ = options.declutterMode;
}
/**
* Clones the style.
* @return {ImageStyle} The cloned style.
* @api
*/
clone() {
const scale = this.getScale();
return new ImageStyle({
opacity: this.getOpacity(),
scale: Array.isArray(scale) ? scale.slice() : scale,
rotation: this.getRotation(),
rotateWithView: this.getRotateWithView(),
displacement: this.getDisplacement().slice(),
declutterMode: this.getDeclutterMode(),
});
}
/**
* Get the symbolizer opacity.
* @return {number} Opacity.
* @api
*/
getOpacity() {
return this.opacity_;
}
/**
* Determine whether the symbolizer rotates with the map.
* @return {boolean} Rotate with map.
* @api
*/
getRotateWithView() {
return this.rotateWithView_;
}
/**
* Get the symoblizer rotation.
* @return {number} Rotation.
* @api
*/
getRotation() {
return this.rotation_;
}
/**
* Get the symbolizer scale.
* @return {number|import("../size.js").Size} Scale.
* @api
*/
getScale() {
return this.scale_;
}
/**
* Get the symbolizer scale array.
* @return {import("../size.js").Size} Scale array.
*/
getScaleArray() {
return this.scaleArray_;
}
/**
* Get the displacement of the shape
* @return {Array<number>} Shape's center displacement
* @api
*/
getDisplacement() {
return this.displacement_;
}
/**
* Get the declutter mode of the shape
* @return {"declutter"|"obstacle"|"none"|undefined} Shape's declutter mode
* @api
*/
getDeclutterMode() {
return this.declutterMode_;
}
/**
* Get the anchor point in pixels. The anchor determines the center point for the
* symbolizer.
* @abstract
* @return {Array<number>} Anchor.
*/
getAnchor() {
return abstract();
}
/**
* Get the image element for the symbolizer.
* @abstract
* @param {number} pixelRatio Pixel ratio.
* @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
*/
getImage(pixelRatio) {
return abstract();
}
/**
* @abstract
* @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
*/
getHitDetectionImage() {
return abstract();
}
/**
* Get the image pixel ratio.
* @param {number} pixelRatio Pixel ratio.
* @return {number} Pixel ratio.
*/
getPixelRatio(pixelRatio) {
return 1;
}
/**
* @abstract
* @return {import("../ImageState.js").default} Image state.
*/
getImageState() {
return abstract();
}
/**
* @abstract
* @return {import("../size.js").Size} Image size.
*/
getImageSize() {
return abstract();
}
/**
* Get the origin of the symbolizer.
* @abstract
* @return {Array<number>} Origin.
*/
getOrigin() {
return abstract();
}
/**
* Get the size of the symbolizer (in pixels).
* @abstract
* @return {import("../size.js").Size} Size.
*/
getSize() {
return abstract();
}
/**
* Set the displacement.
*
* @param {Array<number>} displacement Displacement.
* @api
*/
setDisplacement(displacement) {
this.displacement_ = displacement;
}
/**
* Set the opacity.
*
* @param {number} opacity Opacity.
* @api
*/
setOpacity(opacity) {
this.opacity_ = opacity;
}
/**
* Set whether to rotate the style with the view.
*
* @param {boolean} rotateWithView Rotate with map.
* @api
*/
setRotateWithView(rotateWithView) {
this.rotateWithView_ = rotateWithView;
}
/**
* Set the rotation.
*
* @param {number} rotation Rotation.
* @api
*/
setRotation(rotation) {
this.rotation_ = rotation;
}
/**
* Set the scale.
*
* @param {number|import("../size.js").Size} scale Scale.
* @api
*/
setScale(scale) {
this.scale_ = scale;
this.scaleArray_ = toSize(scale);
}
/**
* @abstract
* @param {function(import("../events/Event.js").default): void} listener Listener function.
*/
listenImageChange(listener) {
abstract();
}
/**
* Load not yet loaded URI.
* @abstract
*/
load() {
abstract();
}
/**
* @abstract
* @param {function(import("../events/Event.js").default): void} listener Listener function.
*/
unlistenImageChange(listener) {
abstract();
}
}
export default ImageStyle;