diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index d1eb605bad..5b9ae1a327 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -213,17 +213,27 @@ export interface IBaseTileLayerManager { destroy(): void; } -export interface ITileRenderService { - render(layers: ILayer[]): void; +export interface ITilePickService { + pickRender(target: IInteractionTarget): void; } -export interface ITilePickService { - isLastPicked: boolean; - on(type: string, cb: (option: any) => void): void; - beforeHighlight(pickedColors: any): void; - beforeSelect(pickedColors: any): void; - clearPick(): void; - pick(layers: ILayer[], target: IInteractionTarget): boolean; +export interface ITile { + x: number; + y: number; + z: number; + key: string; + sourceTile: SourceTile; + visible: boolean; + isLoaded: boolean; + getLayers(): ILayer[]; + styleUpdate(...args: any): void; + initTileLayer(): Promise; + lnglatInBounds(lnglat: { + lng: number; + lat: number; + }): boolean; + updateVisible(value: boolean): void; + updateOptions(key: string, value: any): void; destroy(): void; } diff --git a/packages/layers/src/tile/interaction/TilePickService.ts b/packages/layers/src/tile/interaction/TilePickService.ts deleted file mode 100644 index f0e8295965..0000000000 --- a/packages/layers/src/tile/interaction/TilePickService.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { - ILayer, - IPickingService, - IRendererService, - IInteractionTarget, - ITileRenderService, - ILayerService, - TYPES, - } from '@antv/l7-core'; -import { EventEmitter } from 'eventemitter3'; - -export class TilePickService extends EventEmitter{ - public isLastPicked: boolean = false; - private rendererService: IRendererService; - private pickingService: IPickingService; - private layerService: ILayerService; - private children: ILayer[]; - private parent: ILayer; - private tileRenderService: ITileRenderService; - constructor( - parent: ILayer, - rendererService: IRendererService, - pickingService: IPickingService, - children: ILayer[], - tileRenderService: ITileRenderService - ) { - super(); - this.parent = parent; - this.rendererService = rendererService; - this.pickingService = pickingService; - this.children = children; - this.tileRenderService = tileRenderService; - const container = this.parent.getContainer(); - this.layerService = container.get(TYPES.ILayerService); - } - - - - public pick(layers: ILayer[], target: IInteractionTarget) { - // Tip: 在进行拾取渲染的时候也需要先渲染一遍父组件然后再渲染子组件 - // 如需要在 栅格瓦片存在 Mask 的时候发生的拾取,那么就需要先渲染父组件(渲染父组件的帧缓冲) - this.layerService.renderMask(this.parent.masks); - - const isPicked = layers - .filter( - (layer) => - this.parent.needPick(target.type) && - layer.inited && - layer.isVisible(), - ) - .some((layer) => { - layer.hooks.beforePickingEncode.call(); - if (layer.masks.length > 0) { - // 清除上一次的模版缓存 - this.rendererService.clear({ - stencil: 0, - depth: 1, - framebuffer: null, - }); - - layer.masks.map((m: ILayer) => { - m.hooks.beforeRender.call(); - m.render(); - m.hooks.afterRender.call(); - }); - } - layer.renderModels(true); - layer.hooks.afterPickingEncode.call(); - const layerPicked = this.pickingService.pickFromPickingFBO( - layer, - target, - ); - // RasterLayer 不参与拾取后的 shader 计算 - if (layerPicked && this.parent.type !== 'RasterLayer') { - this.emit('pick', { - type: target.type, - pickedColors: this.pickingService.pickedColors, - layer, - }); - this.pickingService.pickedTileLayers = [this.parent]; - } - - return layerPicked; - }); - if ( - this.parent.type !== 'RasterLayer' && - !isPicked && - this.isLastPicked && - target.type !== 'click' - ) { - // 只有上一次有被高亮选中,本次未选中的时候才需要清除选中状态 - this.pickingService.pickedTileLayers = []; - this.emit('unpick', {}); - this.beforeHighlight([0, 0, 0]); - } - this.isLastPicked = isPicked; - return isPicked; - } - - public clearPick() { - this.children - .filter((child) => child.inited && child.isVisible()) - .map((layer) => { - layer.hooks.beforeSelect.call([0, 0, 0]); - }); - this.pickingService.pickedTileLayers = []; - } - - public beforeHighlight(pickedColors: any) { - this.children - .filter((child) => child.inited && child.isVisible()) - .map((child) => { - child.hooks.beforeHighlight.call(pickedColors); - }); - } - - public beforeSelect(pickedColors: any) { - this.children - .filter((child) => child.inited && child.isVisible()) - .map((layer) => { - layer.hooks.beforeSelect.call(pickedColors); - }); - } - - public destroy(): void { - this.removeAllListeners(); - } -} \ No newline at end of file diff --git a/packages/layers/src/tile/manager/mapLayerManager.ts b/packages/layers/src/tile/manager/mapLayerManager.ts deleted file mode 100644 index 248195a447..0000000000 --- a/packages/layers/src/tile/manager/mapLayerManager.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - ILayer, - IMapService, - IRendererService, - ISubLayerInitOptions, - IBaseTileLayerManager, -} from '@antv/l7-core'; -import { Base } from './base'; -import { getLayerShape, getMaskValue } from '../utils'; -export class BaseMapTileLayerManager extends Base implements IBaseTileLayerManager { - // only support vector layer - constructor( - parent: ILayer, - mapService: IMapService, - rendererService: IRendererService, - ) { - super(); - this.parent = parent; - this.children = parent.layerChildren; - this.mapService = mapService; - this.rendererService = rendererService; - - - this.setSubLayerInitOption(); - this.initTileFactory(); - } - - public render(): void { - this.children - .filter((layer) => layer.inited) - .filter((layer) => layer.isVisible()) - .map(async (layer) => { - if (layer.masks.length > 0) { - // 清除上一次的模版缓存 - this.rendererService.clear({ - stencil: 0, - depth: 1, - framebuffer: null, - }); - layer.masks.map((m: ILayer) => { - m.render(); - }); - } - layer.render(); - }); - } - - private setSubLayerInitOption() { - const { - zIndex = 0, - opacity = 1, - mask = false, - stroke = '#fff', - strokeWidth = 0, - strokeOpacity = 1, - - workerEnabled = false, - sourceLayer, - } = this.parent.getLayerConfig() as ISubLayerInitOptions; - - const source = this.parent.getSource(); - const parentParserType = source.getParserType(); - - const colorAttribute = this.parent.getAttribute('color'); - const basemapColor = (colorAttribute?.scale?.field || '#fff') as string; - const sizeAttribute = this.parent.getAttribute('size'); - const basemapSize = (sizeAttribute?.scale?.field || 1) as number; - - const layerShape = getLayerShape(this.parent.type, this.parent); - - this.initOptions = { - usage: 'basemap', - visible: true, - layerType: this.parent.type, - shape: layerShape, - zIndex, - opacity, - sourceLayer: this.getSourceLayer(parentParserType, sourceLayer), - basemapColor, - basemapSize, - mask: getMaskValue(this.parent.type, mask), - stroke, - strokeWidth, - strokeOpacity, - // worker - workerEnabled, - }; - } -} diff --git a/packages/layers/src/tile/render/TileRenderService.ts b/packages/layers/src/tile/render/TileRenderService.ts deleted file mode 100644 index 673a6d56d6..0000000000 --- a/packages/layers/src/tile/render/TileRenderService.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ILayer, IRendererService, ITileRenderService } from '@antv/l7-core'; -/** - * 主要用于瓦片图层队列的渲染 - */ -export class TileRenderService implements ITileRenderService{ - private rendererService: IRendererService; - - constructor(rendererService: IRendererService) { - this.rendererService = rendererService; - } - - public render(layers: ILayer[]) { - layers - .filter((layer) => layer.inited) - .filter((layer) => layer.isVisible()) - .map(async (layer) => { - if (layer.masks.length > 0) { - // 清除上一次的模版缓存 - this.rendererService.clear({ - stencil: 0, - depth: 1, - framebuffer: null, - }); - layer.masks.map(async (m: ILayer) => { - m.render(); - }); - } - layer.render(); - }); - } -} \ No newline at end of file diff --git a/packages/layers/src/tile/service/TilePickService.ts b/packages/layers/src/tile/service/TilePickService.ts index d7a89a28cb..80679a67fa 100644 --- a/packages/layers/src/tile/service/TilePickService.ts +++ b/packages/layers/src/tile/service/TilePickService.ts @@ -1,4 +1,4 @@ -import { ILayerService, ITile } from '@antv/l7-core'; +import { ILayerService, ITile, ITilePickService } from '@antv/l7-core'; import { TileLayerService } from './TileLayerService'; import { IInteractionTarget } from '@antv/l7-core'; export interface ITilePickServiceOptions { @@ -8,7 +8,7 @@ export interface ITilePickServiceOptions { const SELECT = 'select'; const ACTIVE = 'active'; -export class TilePickService { +export class TilePickService implements ITilePickService{ private layerService: ILayerService; private tileLayerService: TileLayerService; private tilePickID = new Map(); diff --git a/packages/layers/src/tile/style/TileStyleService.ts b/packages/layers/src/tile/style/TileStyleService.ts deleted file mode 100644 index 810b69aab6..0000000000 --- a/packages/layers/src/tile/style/TileStyleService.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { ILayer, IScaleValue, ISubLayerInitOptions } from '@antv/l7-core'; -import EventEmitter from 'eventemitter3'; -import { isEqual } from 'lodash'; -export interface ITileStyleService { - setConfig(key: string, value: any): void; - checkConfig(layer: ILayer): void; - on(event: string, fn: (...args: any[]) => void): void; - getAttributeScale(layer: ILayer, name: string): IScaleValue; -} - -export class TileStyleService extends EventEmitter { - public cacheConfig: Map; - public checkConfigList: string[] = []; - constructor() { - super(); - this.cacheConfig = new Map(); - } - - public setConfig(key: string, value: any) { - if (!this.checkConfigList.includes(key)) { - this.checkConfigList.push(key); - } - this.cacheConfig.set(key, value); - } - - public removeConfig(key: string) { - const configIndex = this.checkConfigList.indexOf(key); - if (configIndex > -1) { - this.cacheConfig.delete(key); - this.checkConfigList.splice(configIndex, 1); - } - } - - public checkConfig(layer: ILayer) { - if (!layer.inited) { - return; - } - - const layerConfig = layer.getLayerConfig() as ISubLayerInitOptions; - const updateConfigs: string[] = []; - this.checkConfigList.map((key) => { - const cacheConfig = this.cacheConfig.get(key); - - let currentConfig; - if (['color', 'size', 'shape'].includes(key)) { - currentConfig = layer.getAttribute(key)?.scale; - } else { - if (!(key in layerConfig)) { - return; - } - // @ts-ignore - currentConfig = layerConfig[key]; - } - - if (!isEqual(cacheConfig, currentConfig)) { - updateConfigs.push(key); - this.setConfig(key, currentConfig); - } - }); - if (updateConfigs.length > 0) { - console.warn('tile config cache update!', updateConfigs); - this.emit('updateConfig', updateConfigs); - } - } - - public getAttributeScale(layer: ILayer, name: string): IScaleValue { - const attribute = layer.getAttribute(name); - const scaleValue: IScaleValue = { - field: undefined, - values: undefined, - callback: undefined, - }; - if (attribute && attribute.scale) { - const { field, values, callback } = attribute.scale; - scaleValue.field = field; - scaleValue.values = values; - scaleValue.callback = callback; - } - return scaleValue; - } -} diff --git a/packages/layers/src/tile/style/constants.ts b/packages/layers/src/tile/style/constants.ts index 0362e4e9a3..19db4fb497 100644 --- a/packages/layers/src/tile/style/constants.ts +++ b/packages/layers/src/tile/style/constants.ts @@ -1,58 +1,20 @@ -/** - * 瓦片图层的样式 - */ - -export const Attributes = ['size', 'color', 'shape']; - -const common = [ - 'opacity', - 'zIndex', -] -const rasterLayer = [ - 'mask', - 'rampColors', - 'domain', - 'clampHigh', - 'clampLow', - 'pixelConstant', - 'pixelConstantR', - 'pixelConstantG', - 'pixelConstantB', - 'pixelConstantRGB', - ...common -] -const pointLayer = [ - 'stroke', - 'strokeWidth', - 'strokeOpacity', - 'color', +// TileLayer 需要代理的子图层的方法 +// 一般都是在 BaseLayer 上的方法 +export const ProxyFuncs = [ + /** + * 1. 需要作用到所属子图层才会生效的方法 + * 2. 不需要主动重新创建 model 的方法 + */ 'shape', + 'color', 'size', - ...common + 'style', + 'animate', + 'filter', + 'rotate', + 'scale', + 'setBlend', + 'setSelect', + 'setActive', ] -const lineLayer = [ - 'stroke', - 'strokeWidth', - 'strokeOpacity', - 'color', - 'shape', - 'size', - ...common -] -const polygonLayer = [ - 'color', - 'shape', - ...common -] -export type IStyles = 'PointLayer'| 'LineLayer' | 'PolygonLayer' | 'RasterLayer' | 'MaskLayer' | 'TileDebugLayer'; -export const styles = { - 'PointLayer': pointLayer, - 'LineLayer': lineLayer, - 'PolygonLayer': polygonLayer, - - 'RasterLayer': rasterLayer, - - 'MaskLayer': [], - 'TileDebugLayer': [], -} diff --git a/packages/layers/src/tile/style/style.ts b/packages/layers/src/tile/style/style.ts deleted file mode 100644 index fd1e11b78b..0000000000 --- a/packages/layers/src/tile/style/style.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { ILayer } from "@antv/l7-core"; - -const ProxyFuncs = [ - /** - * 1. 需要作用到所属子图层才会生效的方法 - * 2. 不需要主动重新创建 model 的方法 - */ - 'shape', - 'color', - 'size', - 'style', - 'filter', - 'rotate', - 'scale', - 'setBlend', - 'setSelect', - 'setActive', -] - -export class LayerStyleProxy { - - getLayers(layer: ILayer){ - return layer.tileLayer.getLayers(); - } - - getTiles(layer: ILayer) { - return layer.tileLayer.tileLayerService.getTiles(); - } - - proxy(parent: ILayer) { - ProxyFuncs.forEach(func => { - // @ts-ignore - const oldStyleFunc = parent[func].bind(parent); - // @ts-ignore - parent[func] = (...args: any) => { - oldStyleFunc(...args); - this.getLayers(parent).map(child =>{ - // @ts-ignore - child[func](...args); - }) - // Tip: 目前在更新 RasterData 的 colorTexture 的时候需要额外优化 - if(func === 'style') { - this.getTiles(parent).forEach(tile => tile.styleUpdate(...args)); - } - - return parent; - } - }) - } - -} - -// const oldStyleFunc = parent.color.bind(parent); -// parent.color = (...args) => { -// oldStyleFunc(...args); -// getLayers(parent).map(child =>{ -// child.color(...args); -// }) -// return parent; -// } \ No newline at end of file diff --git a/packages/layers/src/tile/style/utils.ts b/packages/layers/src/tile/style/utils.ts index caa3b019fc..f4cb16ea54 100644 --- a/packages/layers/src/tile/style/utils.ts +++ b/packages/layers/src/tile/style/utils.ts @@ -1,27 +1,4 @@ -import { - ILayer, - IRendererService, - } from '@antv/l7-core'; - - import { generateColorRamp, IColorRamp } from '@antv/l7-utils'; - -export function updateTexture(config: IColorRamp, layers: ILayer[], rendererService: IRendererService) { - const { createTexture2D } = rendererService; - const imageData = generateColorRamp(config) as ImageData; - const texture = createTexture2D({ - data: imageData.data, - width: imageData.width, - height: imageData.height, - flipY: false, - }); - - layers.map(layer => { - layer.updateLayerConfig({ - colorTexture: texture - }); - }) - return texture; -} +import { ILayer } from '@antv/l7-core'; export function updateLayersConfig(layers: ILayer[], key: string, value: any) { layers.map((layer) => { @@ -38,39 +15,3 @@ export function updateLayersConfig(layers: ILayer[], key: string, value: any) { }); } - -export function getDefaultStyleAttributeField(layer: ILayer, type: string, style: string) { - switch (style) { - case 'size': - return 1; - case 'color': - return '#fff'; - case 'shape': - return getLayerShape(type, layer); - default: - return ''; - } -} - -export function getLayerShape(layerType: string, layer: ILayer) { - const layerShape = layer.getAttribute('shape'); - if (layerShape && layerShape.scale?.field) { - if (layerShape.scale?.values === 'text') { - return [layerShape.scale.field, layerShape.scale.values] as string[]; - } - return layerShape.scale.field as string; - } - switch (layerType) { - case 'PolygonLayer': - return 'fill'; - case 'LineLayer': - return 'tileline'; - case 'PointLayer': - return 'circle'; - case 'RasterLayer': - return 'image'; - default: - return ''; - } -} - diff --git a/packages/layers/src/tile/tileLayer/BaseLayer.ts b/packages/layers/src/tile/tileLayer/BaseLayer.ts index 125bc5a835..212aeaec2f 100644 --- a/packages/layers/src/tile/tileLayer/BaseLayer.ts +++ b/packages/layers/src/tile/tileLayer/BaseLayer.ts @@ -13,11 +13,11 @@ import { TileLayerService } from '../service/TileLayerService'; import { TilePickService } from '../service/TilePickService'; import { debounce } from 'lodash'; import { getTileFactory } from '../tileFactory'; -import { LayerStyleProxy } from '../style/style'; +import { ProxyFuncs } from '../style/constants'; export default class BaseTileLayer { private parent: ILayer; - private layerStyleProxy: LayerStyleProxy; + public tileLayerService: TileLayerService; protected mapService: IMapService; protected layerService: ILayerService; @@ -34,7 +34,6 @@ export default class BaseTileLayer { constructor(parent: ILayer) { this.parent = parent; - this.layerStyleProxy = new LayerStyleProxy(); const container = this.parent.getContainer(); this.rendererService = container.get( TYPES.IRendererService, @@ -59,7 +58,7 @@ export default class BaseTileLayer { // 重置 this.parent.setLayerPickService(this.tilePickService); - this.layerStyleProxy.proxy(this.parent); + this.proxy(parent); this.initTileSetManager(); @@ -241,4 +240,30 @@ export default class BaseTileLayer { } + /** + * 实现 TileLayer 对子图层方法的代理 + * @param parent + */ + private proxy(parent: ILayer) { + ProxyFuncs.forEach(func => { + // @ts-ignore + const oldStyleFunc = parent[func].bind(parent); + // @ts-ignore + parent[func] = (...args: any) => { + oldStyleFunc(...args); + this.getLayers().map(child =>{ + // @ts-ignore + child[func](...args); + }) + // Tip: 目前在更新 RasterData 的 colorTexture 的时候需要额外优化 + if(func === 'style') { + this.getTiles().forEach(tile => tile.styleUpdate(...args)); + } + + return parent; + } + }) +} + + } diff --git a/packages/layers/src/tile/utils.ts b/packages/layers/src/tile/utils.ts index 5b46a21e54..7fa91b2370 100644 --- a/packages/layers/src/tile/utils.ts +++ b/packages/layers/src/tile/utils.ts @@ -1,6 +1,5 @@ -import { createLayerContainer, ILayer } from '@antv/l7-core'; +import { ILayer } from '@antv/l7-core'; import { DOM } from '@antv/l7-utils'; -import { Container } from 'inversify'; export const tileVectorParser = ['mvt', 'geojsonvt', 'testTile']; @@ -14,53 +13,6 @@ export function isTileGroup(layer: ILayer) { return tileVectorParser.includes(source.parser.type); } -export function registerLayers(parentLayer: ILayer, layers: ILayer[]) { - layers.map((layer) => { - const container = createLayerContainer( - parentLayer.sceneContainer as Container, - ); - layer.setContainer(container, parentLayer.sceneContainer as Container); - layer.init(); - }); -} - -export function getLayerShape(layerType: string, layer: ILayer) { - const layerShape = layer.getAttribute('shape'); - if (layerShape && layerShape.scale?.field) { - if (layerShape.scale?.values === 'text') { - return [layerShape.scale.field, layerShape.scale.values] as string[]; - } - return layerShape.scale.field as string; - } - switch (layerType) { - case 'PolygonLayer': - return 'fill'; - case 'LineLayer': - return 'tileline'; - case 'PointLayer': - return 'circle'; - case 'RasterLayer': - return 'image'; - default: - return ''; - } -} - -export function getMaskValue(layerType: string, mask: boolean) { - switch (layerType) { - case 'PolygonLayer': - return true; - case 'LineLayer': - return true; - case 'PointLayer': - return false; - case 'RasterLayer': - return mask; - default: - return mask; - } -} - export function getContainerSize(container: HTMLCanvasElement | HTMLElement) { if ((container as HTMLCanvasElement).getContext) { return {