UNPKG

@giro3d/giro3d

Version:

A JS/WebGL framework for 3D geospatial data visualization

113 lines (94 loc) 3.01 kB
/* * Copyright (c) 2015-2018, IGN France. * Copyright (c) 2018-2026, Giro3D team. * SPDX-License-Identifier: MIT */ import { type Feature } from 'ol'; import { type Geometry } from 'ol/geom'; import { Texture, UnsignedByteType, type TextureDataType } from 'three'; import type { LayerOptions, LayerUserData, Target } from './Layer'; import OffsetScale from '../OffsetScale'; import ColorLayer from './ColorLayer'; /** * Modes of the mask layer. */ export enum MaskMode { /** * The mask is applied normally: transparents parts of the mask make the map transparent. */ Normal = 1, /** * The mask is inverted: transparents parts of the mask make the map opaque. */ Inverted = 2, } const EMPTY_TEXTURE = new Texture(); const DEFAULT_PITCH = OffsetScale.identity(); export interface MaskLayerOptions extends LayerOptions { /** * How to interpret the mask. */ maskMode?: MaskMode; } /** * A {@link ColorLayer} that can be used to mask parts of * a map. The source can be any source supported by the color layers. * */ export class MaskLayer< UserData extends LayerUserData = LayerUserData, > extends ColorLayer<UserData> { private _maskMode: MaskMode; /** * Read-only flag to check if a given object is of type MaskLayer. */ public readonly isMaskLayer: boolean = true; /** * Creates a mask layer. * It should be added in a `Map` to be displayed in the instance. * See the example for more information on layer creation. * * @param options - The layer options. */ public constructor(options: MaskLayerOptions) { super(options); this.isMaskLayer = true; this.type = 'MaskLayer'; this._maskMode = options.maskMode ?? MaskMode.Normal; } /** * Gets or set the mask mode. */ public get maskMode(): MaskMode { return this._maskMode; } public set maskMode(v: MaskMode) { this._maskMode = v; } public override getRenderTargetDataType(): TextureDataType { return UnsignedByteType; } public override applyEmptyTextureToNode(target: Target): void { const material = target.node.material; if (!material.hasColorLayer(this)) { material.pushColorLayer(this, target.extent); } // We cannot remove the layer from the material, contrary to what is done for // other layer types, because since this layer acts as a mask, it must be defined // for the entire map. material.setColorTextures(this, { texture: EMPTY_TEXTURE, pitch: DEFAULT_PITCH, }); } public override getVectorFeaturesAtCoordinate(): Feature<Geometry>[] { return []; } public override getVectorFeaturesInExtent(): Feature<Geometry>[] { return []; } } export function isMaskLayer(obj: unknown): obj is MaskLayer { return (obj as MaskLayer)?.isMaskLayer; } export default MaskLayer;