mirror of https://gitee.com/antv-l7/antv-l7
feat: 瓦片性能和代码优化 (#1347)
* fix: 修复 featureScale 错误 * style: lint style * fix: remove featureScalePlugin async * feat: 优化数据栅格瓦片的渲染、瓦片管理流程完善 * style: lint style Co-authored-by: shihui <yiqianyao.yqy@alibaba-inc.com>
This commit is contained in:
parent
c95f70fa92
commit
a2e525e12b
|
@ -109,6 +109,16 @@ export default () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
scene.addLayer(layer);
|
scene.addLayer(layer);
|
||||||
|
|
||||||
|
// setTimeout(() => {
|
||||||
|
// layer.style({
|
||||||
|
// rampColors: {
|
||||||
|
// colors: ['#f00', '#ff0'],
|
||||||
|
// positions: [0, 1]
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// scene.render()
|
||||||
|
// }, 2000)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { SyncBailHook, SyncHook, SyncWaterfallHook } from '@antv/async-hook';
|
import { SyncBailHook, SyncHook, SyncWaterfallHook } from '@antv/async-hook';
|
||||||
import { IColorRamp, IImagedata, Tile, TilesetManager } from '@antv/l7-utils';
|
import { IColorRamp, Tile, TilesetManager } from '@antv/l7-utils';
|
||||||
import { Container } from 'inversify';
|
import { Container } from 'inversify';
|
||||||
import Clock from '../../utils/clock';
|
import Clock from '../../utils/clock';
|
||||||
import { ISceneConfig } from '../config/IConfigService';
|
import { ISceneConfig } from '../config/IConfigService';
|
||||||
|
@ -37,10 +37,6 @@ import {
|
||||||
Triangulation,
|
Triangulation,
|
||||||
} from './IStyleAttributeService';
|
} from './IStyleAttributeService';
|
||||||
|
|
||||||
// import {
|
|
||||||
// IStyleAttributeUpdateOptions,
|
|
||||||
// StyleAttributeField,
|
|
||||||
// } from '@antv/l7-core';y
|
|
||||||
export enum BlendType {
|
export enum BlendType {
|
||||||
normal = 'normal',
|
normal = 'normal',
|
||||||
additive = 'additive',
|
additive = 'additive',
|
||||||
|
@ -162,7 +158,6 @@ export interface ISubLayerInitOptions {
|
||||||
rampColors?: IColorRamp;
|
rampColors?: IColorRamp;
|
||||||
colorTexture?: ITexture2D;
|
colorTexture?: ITexture2D;
|
||||||
// 在初始化的时候使用
|
// 在初始化的时候使用
|
||||||
rampColorsData?: ImageData | IImagedata;
|
|
||||||
|
|
||||||
pixelConstant?: number;
|
pixelConstant?: number;
|
||||||
pixelConstantR?: number;
|
pixelConstantR?: number;
|
||||||
|
@ -185,6 +180,7 @@ export interface ITilePickManager {
|
||||||
beforeSelect(pickedColors: any): void;
|
beforeSelect(pickedColors: any): void;
|
||||||
clearPick(): void;
|
clearPick(): void;
|
||||||
pickRender(layers: ILayer[], target: IInteractionTarget): boolean;
|
pickRender(layers: ILayer[], target: IInteractionTarget): boolean;
|
||||||
|
destroy(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBaseTileLayerManager {
|
export interface IBaseTileLayerManager {
|
||||||
|
@ -202,12 +198,13 @@ export interface IBaseTileLayerManager {
|
||||||
clearChild(): void;
|
clearChild(): void;
|
||||||
hasChild(layer: ILayer): boolean;
|
hasChild(layer: ILayer): boolean;
|
||||||
render(isPicking?: boolean): void;
|
render(isPicking?: boolean): void;
|
||||||
updateLayersConfig(layers: ILayer[], key: string, value: any): void;
|
destroy(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITileLayerManager extends IBaseTileLayerManager{
|
export interface ITileLayerManager extends IBaseTileLayerManager{
|
||||||
tilePickManager: ITilePickManager;
|
tilePickManager: ITilePickManager;
|
||||||
pickLayers(target: IInteractionTarget): boolean;
|
pickLayers(target: IInteractionTarget): boolean;
|
||||||
|
destroy(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBaseTileLayer {
|
export interface IBaseTileLayer {
|
||||||
|
@ -219,12 +216,14 @@ export interface IBaseTileLayer {
|
||||||
children: ILayer[];
|
children: ILayer[];
|
||||||
scaleField: any;
|
scaleField: any;
|
||||||
render(isPicking?: boolean): void;
|
render(isPicking?: boolean): void;
|
||||||
|
destroy(): void;
|
||||||
}
|
}
|
||||||
export interface ITileLayer extends IBaseTileLayer{
|
export interface ITileLayer extends IBaseTileLayer{
|
||||||
tileLayerManager: ITileLayerManager;
|
tileLayerManager: ITileLayerManager;
|
||||||
pickLayers(target: IInteractionTarget): boolean;
|
pickLayers(target: IInteractionTarget): boolean;
|
||||||
clearPick(type: string): void;
|
clearPick(type: string): void;
|
||||||
clearPickState(): void;
|
clearPickState(): void;
|
||||||
|
destroy(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITileLayerOPtions {
|
export interface ITileLayerOPtions {
|
||||||
|
|
|
@ -977,10 +977,11 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
||||||
// 执行每个图层单独的 clearModels 方法 (清除一些额外的 texture、program、buffer 等)
|
// 执行每个图层单独的 clearModels 方法 (清除一些额外的 texture、program、buffer 等)
|
||||||
|
|
||||||
this.hooks.afterDestroy.call();
|
this.hooks.afterDestroy.call();
|
||||||
|
|
||||||
// Tip: 清除各个图层自定义的 models 资源
|
// Tip: 清除各个图层自定义的 models 资源
|
||||||
this.layerModel?.clearModels(refresh);
|
this.layerModel?.clearModels(refresh);
|
||||||
|
|
||||||
|
this.tileLayer?.destroy();
|
||||||
|
|
||||||
this.models = [];
|
this.models = [];
|
||||||
|
|
||||||
this.layerService.cleanRemove(this, refresh);
|
this.layerService.cleanRemove(this, refresh);
|
||||||
|
|
|
@ -272,6 +272,7 @@ export interface IHeatMapLayerStyleOptions extends IBaseLayerStyleOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRasterLayerStyleOptions extends IBaseLayerStyleOptions {
|
export interface IRasterLayerStyleOptions extends IBaseLayerStyleOptions {
|
||||||
|
colorTexture?: ITexture2D;
|
||||||
domain: [number, number];
|
domain: [number, number];
|
||||||
noDataValue: number;
|
noDataValue: number;
|
||||||
clampLow: boolean;
|
clampLow: boolean;
|
||||||
|
|
|
@ -50,6 +50,5 @@ export default class RaterLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
||||||
default:
|
default:
|
||||||
return 'raster';
|
return 'raster';
|
||||||
}
|
}
|
||||||
// return 'raster';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
import {
|
||||||
|
AttributeType,
|
||||||
|
gl,
|
||||||
|
IEncodeFeature,
|
||||||
|
IModel,
|
||||||
|
ITexture2D,
|
||||||
|
} from '@antv/l7-core';
|
||||||
|
import { getMask } from '@antv/l7-utils';
|
||||||
|
import BaseModel from '../../core/BaseModel';
|
||||||
|
import { IRasterLayerStyleOptions } from '../../core/interface';
|
||||||
|
import { RasterImageTriangulation } from '../../core/triangulation';
|
||||||
|
import rasterFrag from '../shaders/raster_2d_frag.glsl';
|
||||||
|
import rasterVert from '../shaders/raster_2d_vert.glsl';
|
||||||
|
export default class RasterModel extends BaseModel {
|
||||||
|
protected texture: ITexture2D;
|
||||||
|
public getUninforms() {
|
||||||
|
const { createTexture2D } = this.rendererService;
|
||||||
|
const {
|
||||||
|
colorTexture = createTexture2D({
|
||||||
|
data: [],
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
flipY: false,
|
||||||
|
}),
|
||||||
|
opacity = 1,
|
||||||
|
clampLow = true,
|
||||||
|
clampHigh = true,
|
||||||
|
noDataValue = -9999999,
|
||||||
|
domain = [0, 1],
|
||||||
|
} = this.layer.getLayerConfig() as IRasterLayerStyleOptions;
|
||||||
|
|
||||||
|
return {
|
||||||
|
u_opacity: opacity || 1,
|
||||||
|
u_texture: this.texture,
|
||||||
|
u_domain: domain,
|
||||||
|
u_clampLow: clampLow,
|
||||||
|
u_clampHigh: typeof clampHigh !== 'undefined' ? clampHigh : clampLow,
|
||||||
|
u_noDataValue: noDataValue,
|
||||||
|
u_colorTexture: colorTexture,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public initModels(callbackModel: (models: IModel[]) => void) {
|
||||||
|
const {
|
||||||
|
mask = false,
|
||||||
|
maskInside = true,
|
||||||
|
} = this.layer.getLayerConfig() as IRasterLayerStyleOptions;
|
||||||
|
const source = this.layer.getSource();
|
||||||
|
const { createTexture2D } = this.rendererService;
|
||||||
|
const parserDataItem = source.data.dataArray[0];
|
||||||
|
this.texture = createTexture2D({
|
||||||
|
data: parserDataItem.data,
|
||||||
|
width: parserDataItem.width,
|
||||||
|
height: parserDataItem.height,
|
||||||
|
format: gl.LUMINANCE,
|
||||||
|
type: gl.FLOAT,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.layer
|
||||||
|
.buildLayerModel({
|
||||||
|
moduleName: 'rasterTileImageData',
|
||||||
|
vertexShader: rasterVert,
|
||||||
|
fragmentShader: rasterFrag,
|
||||||
|
triangulation: RasterImageTriangulation,
|
||||||
|
depth: { enable: false },
|
||||||
|
stencil: getMask(mask, maskInside),
|
||||||
|
pick: false,
|
||||||
|
})
|
||||||
|
.then((model) => {
|
||||||
|
callbackModel([model]);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.warn(err);
|
||||||
|
callbackModel([]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public buildModels(callbackModel: (models: IModel[]) => void) {
|
||||||
|
this.initModels(callbackModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearModels(): void {
|
||||||
|
this.texture?.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected registerBuiltinAttributes() {
|
||||||
|
this.styleAttributeService.registerStyleAttribute({
|
||||||
|
name: 'uv',
|
||||||
|
type: AttributeType.Attribute,
|
||||||
|
descriptor: {
|
||||||
|
name: 'a_Uv',
|
||||||
|
buffer: {
|
||||||
|
usage: gl.DYNAMIC_DRAW,
|
||||||
|
data: [],
|
||||||
|
type: gl.FLOAT,
|
||||||
|
},
|
||||||
|
size: 2,
|
||||||
|
update: (
|
||||||
|
feature: IEncodeFeature,
|
||||||
|
featureIdx: number,
|
||||||
|
vertex: number[],
|
||||||
|
) => {
|
||||||
|
return [vertex[3], vertex[4]];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,4 @@ void main() {
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
gl_FragColor.a = gl_FragColor.a * u_opacity ;
|
gl_FragColor.a = gl_FragColor.a * u_opacity ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ varying vec2 v_texCoord;
|
||||||
void main() {
|
void main() {
|
||||||
v_texCoord = a_Uv;
|
v_texCoord = a_Uv;
|
||||||
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy,0., 1.0));
|
|
||||||
|
|
||||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
gl_Position = u_Mvp * (vec4(project_pos.xy,0., 1.0));
|
gl_Position = u_Mvp * (vec4(project_pos.xy,0., 1.0));
|
||||||
|
|
|
@ -5,100 +5,26 @@ import {
|
||||||
ISubLayerInitOptions,
|
ISubLayerInitOptions,
|
||||||
IBaseTileLayerManager,
|
IBaseTileLayerManager,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { Tile } from '@antv/l7-utils';
|
import { TileManager } from './baseTileManager';
|
||||||
import { getTileFactory, ITileFactory, TileType } from '../tileFactory';
|
|
||||||
import { getLayerShape, getMaskValue } from '../utils';
|
import { getLayerShape, getMaskValue } from '../utils';
|
||||||
export class BaseMapTileLayerManager implements IBaseTileLayerManager {
|
export class BaseMapTileLayerManager extends TileManager implements IBaseTileLayerManager {
|
||||||
// only support vector layer
|
// only support vector layer
|
||||||
public sourceLayer: string;
|
|
||||||
public parent: ILayer;
|
|
||||||
public children: ILayer[];
|
|
||||||
public mapService: IMapService;
|
|
||||||
public rendererService: IRendererService;
|
|
||||||
private tileFactory: ITileFactory;
|
|
||||||
private initOptions: ISubLayerInitOptions;
|
|
||||||
constructor(
|
constructor(
|
||||||
parent: ILayer,
|
parent: ILayer,
|
||||||
mapService: IMapService,
|
mapService: IMapService,
|
||||||
rendererService: IRendererService,
|
rendererService: IRendererService,
|
||||||
) {
|
) {
|
||||||
|
super();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.children = parent.layerChildren;
|
this.children = parent.layerChildren;
|
||||||
this.mapService = mapService;
|
this.mapService = mapService;
|
||||||
this.rendererService = rendererService;
|
this.rendererService = rendererService;
|
||||||
|
|
||||||
|
|
||||||
this.setSubLayerInitOptipn();
|
this.setSubLayerInitOption();
|
||||||
this.initTileFactory();
|
this.initTileFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public createTile(tile: Tile) {
|
|
||||||
return this.tileFactory.createTile(tile, this.initOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public updateLayersConfig(layers: ILayer[], key: string, value: any) {
|
|
||||||
layers.map((layer) => {
|
|
||||||
if (key === 'mask') {
|
|
||||||
// Tip: 栅格瓦片生效、设置全局的 mask、瓦片被全局的 mask 影响
|
|
||||||
layer.style({
|
|
||||||
mask: value,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
layer.updateLayerConfig({
|
|
||||||
[key]: value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public addChild(layer: ILayer) {
|
|
||||||
this.children.push(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public addChilds(layers: ILayer[]) {
|
|
||||||
this.children.push(...layers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeChilds(layerIDList: string[], refresh = true) {
|
|
||||||
const remveLayerList: ILayer[] = [];
|
|
||||||
const cacheLayerList: ILayer[] = [];
|
|
||||||
this.children.filter((child) => {
|
|
||||||
layerIDList.includes(child.id)
|
|
||||||
? remveLayerList.push(child)
|
|
||||||
: cacheLayerList.push(child);
|
|
||||||
});
|
|
||||||
remveLayerList.map((layer) => layer.destroy(refresh));
|
|
||||||
this.children = cacheLayerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeChild(layer: ILayer) {
|
|
||||||
const layerIndex = this.children.indexOf(layer);
|
|
||||||
if (layerIndex > -1) {
|
|
||||||
this.children.splice(layerIndex, 1);
|
|
||||||
}
|
|
||||||
layer.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
public getChilds(layerIDList: string[]) {
|
|
||||||
return this.children.filter((child) => layerIDList.includes(child.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public getChild(layerID: string) {
|
|
||||||
return this.children.filter((child) => child.id === layerID)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public clearChild() {
|
|
||||||
this.children.forEach((layer: any) => {
|
|
||||||
layer.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.children.slice(0, this.children.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public hasChild(layer: ILayer) {
|
|
||||||
return this.children.includes(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
this.children
|
this.children
|
||||||
.filter((layer) => layer.inited)
|
.filter((layer) => layer.inited)
|
||||||
|
@ -125,7 +51,7 @@ export class BaseMapTileLayerManager implements IBaseTileLayerManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private setSubLayerInitOptipn() {
|
private setSubLayerInitOption() {
|
||||||
const {
|
const {
|
||||||
zIndex = 0,
|
zIndex = 0,
|
||||||
opacity = 1,
|
opacity = 1,
|
||||||
|
@ -166,26 +92,4 @@ export class BaseMapTileLayerManager implements IBaseTileLayerManager {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSourceLayer(parentParserType: string, sourceLayer: string|undefined) {
|
|
||||||
if(parentParserType === 'geojsonvt') {
|
|
||||||
return 'geojsonvt';
|
|
||||||
} else if(parentParserType === 'testTile') {
|
|
||||||
return 'testTile';
|
|
||||||
} else {
|
|
||||||
return sourceLayer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private initTileFactory() {
|
|
||||||
const source = this.parent.getSource();
|
|
||||||
const TileFactory = getTileFactory(
|
|
||||||
this.parent.type as TileType,
|
|
||||||
source.parser,
|
|
||||||
);
|
|
||||||
this.tileFactory = new TileFactory({
|
|
||||||
parent: this.parent,
|
|
||||||
mapService: this.mapService,
|
|
||||||
rendererService: this.rendererService,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
import {
|
||||||
|
ILayer,
|
||||||
|
IRendererService,
|
||||||
|
IMapService,
|
||||||
|
ISubLayerInitOptions,
|
||||||
|
} from '@antv/l7-core';
|
||||||
|
import { Tile } from '@antv/l7-utils';
|
||||||
|
import { ITileFactory, getTileFactory, TileType } from '../tileFactory';
|
||||||
|
export class TileManager {
|
||||||
|
public sourceLayer: string;
|
||||||
|
public parent: ILayer;
|
||||||
|
public children: ILayer[];
|
||||||
|
public mapService: IMapService;
|
||||||
|
public rendererService: IRendererService;
|
||||||
|
protected tileFactory: ITileFactory;
|
||||||
|
protected initOptions: ISubLayerInitOptions;
|
||||||
|
|
||||||
|
public createTile(tile: Tile) {
|
||||||
|
return this.tileFactory.createTile(tile, this.initOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public addChild(layer: ILayer) {
|
||||||
|
this.children.push(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public addChilds(layers: ILayer[]) {
|
||||||
|
this.children.push(...layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeChilds(layerIDList: string[], refresh = true) {
|
||||||
|
const remveLayerList: ILayer[] = [];
|
||||||
|
const cacheLayerList: ILayer[] = [];
|
||||||
|
this.children.filter((child) => {
|
||||||
|
layerIDList.includes(child.id)
|
||||||
|
? remveLayerList.push(child)
|
||||||
|
: cacheLayerList.push(child);
|
||||||
|
});
|
||||||
|
remveLayerList.map((layer) => layer.destroy(refresh));
|
||||||
|
this.children = cacheLayerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeChild(layer: ILayer) {
|
||||||
|
const layerIndex = this.children.indexOf(layer);
|
||||||
|
if (layerIndex > -1) {
|
||||||
|
this.children.splice(layerIndex, 1);
|
||||||
|
}
|
||||||
|
layer.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getChilds(layerIDList: string[]) {
|
||||||
|
return this.children.filter((child) => layerIDList.includes(child.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public getChild(layerID: string) {
|
||||||
|
return this.children.filter((child) => child.id === layerID)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearChild() {
|
||||||
|
this.children.forEach((layer: any) => {
|
||||||
|
layer.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.children.slice(0, this.children.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public hasChild(layer: ILayer) {
|
||||||
|
return this.children.includes(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public initTileFactory() {
|
||||||
|
const source = this.parent.getSource();
|
||||||
|
const TileFactory = getTileFactory(
|
||||||
|
this.parent.type as TileType,
|
||||||
|
source.parser,
|
||||||
|
);
|
||||||
|
this.tileFactory = new TileFactory({
|
||||||
|
parent: this.parent,
|
||||||
|
mapService: this.mapService,
|
||||||
|
rendererService: this.rendererService,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSourceLayer(parentParserType: string, sourceLayer: string|undefined) {
|
||||||
|
if(parentParserType === 'geojsonvt') {
|
||||||
|
return 'geojsonvt';
|
||||||
|
} else if(parentParserType === 'testTile') {
|
||||||
|
return 'testTile';
|
||||||
|
} else {
|
||||||
|
return sourceLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public destroy(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,22 +10,14 @@ import {
|
||||||
ITransform,
|
ITransform,
|
||||||
ScaleAttributeType,
|
ScaleAttributeType,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { generateColorRamp, IColorRamp, Tile } from '@antv/l7-utils';
|
import { TileManager } from './baseTileManager';
|
||||||
import { getTileFactory, ITileFactory, TileType } from '../tileFactory';
|
import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
|
||||||
import { getLayerShape, getMaskValue } from '../utils';
|
import { getLayerShape, getMaskValue, updateLayersConfig } from '../utils';
|
||||||
import TileConfigManager, { ITileConfigManager } from './tileConfigManager';
|
import TileConfigManager, { ITileConfigManager } from './tileConfigManager';
|
||||||
import TilePickManager from './tilePickerManager';
|
import TilePickManager from './tilePickerManager';
|
||||||
export class TileLayerManager implements ITileLayerManager {
|
export class TileLayerManager extends TileManager implements ITileLayerManager {
|
||||||
public sourceLayer: string;
|
|
||||||
public parent: ILayer;
|
|
||||||
public children: ILayer[];
|
|
||||||
public mapService: IMapService;
|
|
||||||
public rendererService: IRendererService;
|
|
||||||
public tilePickManager: ITilePickManager;
|
public tilePickManager: ITilePickManager;
|
||||||
public tileConfigManager: ITileConfigManager;
|
public tileConfigManager: ITileConfigManager;
|
||||||
private tileFactory: ITileFactory;
|
|
||||||
private initOptions: ISubLayerInitOptions;
|
|
||||||
private rampColorsData: any;
|
|
||||||
private transforms: ITransform[];
|
private transforms: ITransform[];
|
||||||
constructor(
|
constructor(
|
||||||
parent: ILayer,
|
parent: ILayer,
|
||||||
|
@ -34,6 +26,7 @@ export class TileLayerManager implements ITileLayerManager {
|
||||||
pickingService: IPickingService,
|
pickingService: IPickingService,
|
||||||
transforms: ITransform[]
|
transforms: ITransform[]
|
||||||
) {
|
) {
|
||||||
|
super();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.children = parent.layerChildren;
|
this.children = parent.layerChildren;
|
||||||
this.mapService = mapService;
|
this.mapService = mapService;
|
||||||
|
@ -48,78 +41,11 @@ export class TileLayerManager implements ITileLayerManager {
|
||||||
);
|
);
|
||||||
this.tileConfigManager = new TileConfigManager();
|
this.tileConfigManager = new TileConfigManager();
|
||||||
|
|
||||||
this.setSubLayerInitOptipn();
|
this.setSubLayerInitOption();
|
||||||
this.setConfigListener();
|
this.setConfigListener();
|
||||||
this.initTileFactory();
|
this.initTileFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public createTile(tile: Tile) {
|
|
||||||
return this.tileFactory.createTile(tile, this.initOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public updateLayersConfig(layers: ILayer[], key: string, value: any) {
|
|
||||||
layers.map((layer) => {
|
|
||||||
if (key === 'mask') {
|
|
||||||
// Tip: 栅格瓦片生效、设置全局的 mask、瓦片被全局的 mask 影响
|
|
||||||
layer.style({
|
|
||||||
mask: value,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
layer.updateLayerConfig({
|
|
||||||
[key]: value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public addChild(layer: ILayer) {
|
|
||||||
this.children.push(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public addChilds(layers: ILayer[]) {
|
|
||||||
this.children.push(...layers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeChilds(layerIDList: string[], refresh = true) {
|
|
||||||
const remveLayerList: ILayer[] = [];
|
|
||||||
const cacheLayerList: ILayer[] = [];
|
|
||||||
this.children.filter((child) => {
|
|
||||||
layerIDList.includes(child.id)
|
|
||||||
? remveLayerList.push(child)
|
|
||||||
: cacheLayerList.push(child);
|
|
||||||
});
|
|
||||||
remveLayerList.map((layer) => layer.destroy(refresh));
|
|
||||||
this.children = cacheLayerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeChild(layer: ILayer) {
|
|
||||||
const layerIndex = this.children.indexOf(layer);
|
|
||||||
if (layerIndex > -1) {
|
|
||||||
this.children.splice(layerIndex, 1);
|
|
||||||
}
|
|
||||||
layer.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
public getChilds(layerIDList: string[]) {
|
|
||||||
return this.children.filter((child) => layerIDList.includes(child.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public getChild(layerID: string) {
|
|
||||||
return this.children.filter((child) => child.id === layerID)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public clearChild() {
|
|
||||||
this.children.forEach((layer: any) => {
|
|
||||||
layer.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.children.slice(0, this.children.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public hasChild(layer: ILayer) {
|
|
||||||
return this.children.includes(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
this.tileConfigManager?.checkConfig(this.parent);
|
this.tileConfigManager?.checkConfig(this.parent);
|
||||||
this.tilePickManager?.normalRender(this.children);
|
this.tilePickManager?.normalRender(this.children);
|
||||||
|
@ -129,7 +55,7 @@ export class TileLayerManager implements ITileLayerManager {
|
||||||
return this.tilePickManager?.pickRender(this.children, target);
|
return this.tilePickManager?.pickRender(this.children, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setSubLayerInitOptipn() {
|
private setSubLayerInitOption() {
|
||||||
const {
|
const {
|
||||||
zIndex = 0,
|
zIndex = 0,
|
||||||
opacity = 1,
|
opacity = 1,
|
||||||
|
@ -175,19 +101,6 @@ export class TileLayerManager implements ITileLayerManager {
|
||||||
const parentParserType = source.getParserType();
|
const parentParserType = source.getParserType();
|
||||||
|
|
||||||
const layerShape = getLayerShape(this.parent.type, this.parent);
|
const layerShape = getLayerShape(this.parent.type, this.parent);
|
||||||
let colorTexture = undefined;
|
|
||||||
if (rampColors) {
|
|
||||||
// 构建统一的色带贴图
|
|
||||||
const { createTexture2D } = this.rendererService;
|
|
||||||
this.rampColorsData = generateColorRamp(rampColors as IColorRamp);
|
|
||||||
const imageData = generateColorRamp(rampColors as IColorRamp);
|
|
||||||
colorTexture = createTexture2D({
|
|
||||||
data: this.rampColorsData.data,
|
|
||||||
width: imageData.width,
|
|
||||||
height: imageData.height,
|
|
||||||
flipY: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.initOptions = {
|
this.initOptions = {
|
||||||
|
@ -210,8 +123,6 @@ export class TileLayerManager implements ITileLayerManager {
|
||||||
clampHigh,
|
clampHigh,
|
||||||
domain,
|
domain,
|
||||||
rampColors,
|
rampColors,
|
||||||
rampColorsData: this.rampColorsData,
|
|
||||||
colorTexture,
|
|
||||||
// worker
|
// worker
|
||||||
workerEnabled,
|
workerEnabled,
|
||||||
|
|
||||||
|
@ -221,15 +132,17 @@ export class TileLayerManager implements ITileLayerManager {
|
||||||
pixelConstantB,
|
pixelConstantB,
|
||||||
pixelConstantRGB,
|
pixelConstantRGB,
|
||||||
};
|
};
|
||||||
}
|
if (rampColors) {
|
||||||
|
// 构建统一的色带贴图
|
||||||
private getSourceLayer(parentParserType: string, sourceLayer: string|undefined) {
|
const { createTexture2D } = this.rendererService;
|
||||||
if(parentParserType === 'geojsonvt') {
|
const imageData = generateColorRamp(rampColors as IColorRamp) as ImageData;
|
||||||
return 'geojsonvt';
|
const colorTexture = createTexture2D({
|
||||||
} else if(parentParserType === 'testTile') {
|
data: imageData.data,
|
||||||
return 'testTile';
|
width: imageData.width,
|
||||||
} else {
|
height: imageData.height,
|
||||||
return sourceLayer;
|
flipY: false,
|
||||||
|
});
|
||||||
|
this.initOptions.colorTexture = colorTexture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,25 +240,24 @@ export class TileLayerManager implements ITileLayerManager {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const config = layerConfig[style];
|
const config = layerConfig[style];
|
||||||
updateValue = config;
|
updateValue = config;
|
||||||
this.updateLayersConfig(this.children, style, config);
|
updateLayersConfig(this.children, style, config);
|
||||||
if (style === 'rampColors' && config) {
|
if (style === 'rampColors' && config) {
|
||||||
this.rampColorsData = generateColorRamp(config as IColorRamp);
|
const { createTexture2D } = this.rendererService;
|
||||||
|
const imageData = generateColorRamp(config as IColorRamp) as ImageData;
|
||||||
|
this.initOptions.colorTexture = createTexture2D({
|
||||||
|
data: imageData.data,
|
||||||
|
width: imageData.width,
|
||||||
|
height: imageData.height,
|
||||||
|
flipY: false,
|
||||||
|
});
|
||||||
|
updateLayersConfig(this.children, 'colorTexture', this.initOptions.colorTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.initOptions[style] = updateValue;
|
this.initOptions[style] = updateValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private initTileFactory() {
|
public destroy(): void {
|
||||||
const source = this.parent.getSource();
|
this.tilePickManager.destroy();
|
||||||
const TileFactory = getTileFactory(
|
|
||||||
this.parent.type as TileType,
|
|
||||||
source.parser,
|
|
||||||
);
|
|
||||||
this.tileFactory = new TileFactory({
|
|
||||||
parent: this.parent,
|
|
||||||
mapService: this.mapService,
|
|
||||||
rendererService: this.rendererService,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,4 +162,8 @@ export default class TilePickManager extends EventEmitter
|
||||||
layer.hooks.afterRender.call();
|
layer.hooks.afterRender.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public destroy(): void {
|
||||||
|
this.removeAllListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,9 @@ export default class TileModel extends BaseModel {
|
||||||
return this.buildModels();
|
return this.buildModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public clearModels(): void {
|
||||||
|
}
|
||||||
|
|
||||||
public buildModels() {
|
public buildModels() {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,16 @@ export default class RasterTiffTile extends TileFactory {
|
||||||
|
|
||||||
public createTile(tile: Tile, initOptions: ISubLayerInitOptions) {
|
public createTile(tile: Tile, initOptions: ISubLayerInitOptions) {
|
||||||
const {
|
const {
|
||||||
|
colorTexture,
|
||||||
opacity,
|
opacity,
|
||||||
domain,
|
domain,
|
||||||
clampHigh,
|
clampHigh,
|
||||||
clampLow,
|
clampLow,
|
||||||
rampColors,
|
|
||||||
rampColorsData,
|
|
||||||
mask,
|
mask,
|
||||||
} = initOptions;
|
} = initOptions;
|
||||||
|
|
||||||
const rasterdata = tile.data;
|
const rasterData = tile.data;
|
||||||
if (!rasterdata.data) {
|
if (!rasterData.data) {
|
||||||
console.warn('raster data not exist!');
|
console.warn('raster data not exist!');
|
||||||
return {
|
return {
|
||||||
layers: [],
|
layers: [],
|
||||||
|
@ -36,21 +35,20 @@ export default class RasterTiffTile extends TileFactory {
|
||||||
visible: tile.isVisible,
|
visible: tile.isVisible,
|
||||||
mask,
|
mask,
|
||||||
})
|
})
|
||||||
.source(rasterdata.data, {
|
.source(rasterData.data, {
|
||||||
parser: {
|
parser: {
|
||||||
type: 'raster',
|
type: 'raster',
|
||||||
width: rasterdata.width,
|
width: rasterData.width,
|
||||||
height: rasterdata.height,
|
height: rasterData.height,
|
||||||
extent: tile.bboxPolygon.bbox,
|
extent: tile.bboxPolygon.bbox,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.style({
|
.style({
|
||||||
|
colorTexture,
|
||||||
opacity,
|
opacity,
|
||||||
domain,
|
domain,
|
||||||
clampHigh,
|
clampHigh,
|
||||||
clampLow,
|
clampLow,
|
||||||
rampColors,
|
|
||||||
rampColorsData,
|
|
||||||
});
|
});
|
||||||
this.emitEvent([layer], false);
|
this.emitEvent([layer], false);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import BaseLayer from '../../core/BaseLayer';
|
import BaseLayer from '../../core/BaseLayer';
|
||||||
import { IRasterLayerStyleOptions } from '../../core/interface';
|
import { IRasterLayerStyleOptions } from '../../core/interface';
|
||||||
import RasterModel from '../../raster/models/raster';
|
import RasterModel from '../../raster/models/rasterTile';
|
||||||
|
|
||||||
export default class RasterTiffLayer extends BaseLayer<
|
export default class RasterTiffLayer extends BaseLayer<
|
||||||
Partial<IRasterLayerStyleOptions>
|
Partial<IRasterLayerStyleOptions>
|
||||||
|
|
|
@ -176,4 +176,8 @@ export default class BaseTileLayer implements IBaseTileLayer {
|
||||||
|
|
||||||
return { latLonBounds, zoom };
|
return { latLonBounds, zoom };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public destroy() {
|
||||||
|
this.tilesetManager?.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,7 @@ export default class BaseTileLayer implements ITileLayer {
|
||||||
return this.tileLayerManager.pickLayers(target);
|
return this.tileLayerManager.pickLayers(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
public tileLoaded(tile: Tile) {
|
public tileLoaded(tile: Tile) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
@ -331,6 +332,7 @@ export default class BaseTileLayer implements ITileLayer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 瓦片数据加载成功
|
// 瓦片数据加载成功
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
this.tilesetManager.on('tile-loaded', (tile: Tile) => {
|
this.tilesetManager.on('tile-loaded', (tile: Tile) => {
|
||||||
// 将事件抛出,图层上可以监听使用
|
// 将事件抛出,图层上可以监听使用
|
||||||
});
|
});
|
||||||
|
@ -342,6 +344,7 @@ export default class BaseTileLayer implements ITileLayer {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 瓦片数据加载失败
|
// 瓦片数据加载失败
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
this.tilesetManager.on('tile-error', (error, tile: Tile) => {
|
this.tilesetManager.on('tile-error', (error, tile: Tile) => {
|
||||||
// 将事件抛出,图层上可以监听使用
|
// 将事件抛出,图层上可以监听使用
|
||||||
this.tileError(error);
|
this.tileError(error);
|
||||||
|
@ -372,4 +375,9 @@ export default class BaseTileLayer implements ITileLayer {
|
||||||
|
|
||||||
return { latLonBounds, zoom };
|
return { latLonBounds, zoom };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public destroy() {
|
||||||
|
this.tilesetManager?.destroy();
|
||||||
|
this.tileLayerManager.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ILayer } from '@antv/l7-core';
|
import { ILayer } from '@antv/l7-core';
|
||||||
import { Tile } from '@antv/l7-utils';
|
import { Tile } from '@antv/l7-utils';
|
||||||
import BaseTileLayer from './tileLayer/baseMapTileLayer';
|
import BaseTileLayer from './tileLayer/baseMapTileLayer';
|
||||||
import { tileAllLoad } from './utils';
|
import { tileAllLoad, updateLayersConfig } from './utils';
|
||||||
|
|
||||||
export class TMSBaseMapTileLayer extends BaseTileLayer {
|
export class TMSBaseMapTileLayer extends BaseTileLayer {
|
||||||
public type: string = 'BaseMapTMS';
|
public type: string = 'BaseMapTMS';
|
||||||
|
@ -58,11 +58,7 @@ export class TMSBaseMapTileLayer extends BaseTileLayer {
|
||||||
|
|
||||||
private updateTileVisible(tile: Tile, layers: ILayer[]) {
|
private updateTileVisible(tile: Tile, layers: ILayer[]) {
|
||||||
this.emitTileVisibleEvent(tile, () => {
|
this.emitTileVisibleEvent(tile, () => {
|
||||||
this.tileLayerManager.updateLayersConfig(
|
updateLayersConfig(layers, 'visible', tile.isVisible);
|
||||||
layers,
|
|
||||||
'visible',
|
|
||||||
tile.isVisible,
|
|
||||||
);
|
|
||||||
this.layerService.reRender();
|
this.layerService.reRender();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ILayer } from '@antv/l7-core';
|
import { ILayer } from '@antv/l7-core';
|
||||||
import { Tile } from '@antv/l7-utils';
|
import { Tile } from '@antv/l7-utils';
|
||||||
import BaseTileLayer from './tileLayer/baseTileLayer';
|
import BaseTileLayer from './tileLayer/baseTileLayer';
|
||||||
import { tileAllLoad } from './utils';
|
import { tileAllLoad, updateLayersConfig } from './utils';
|
||||||
|
|
||||||
export class TMSTileLayer extends BaseTileLayer {
|
export class TMSTileLayer extends BaseTileLayer {
|
||||||
public type: string = 'TMS';
|
public type: string = 'TMS';
|
||||||
|
@ -60,11 +60,7 @@ export class TMSTileLayer extends BaseTileLayer {
|
||||||
|
|
||||||
private updateTileVisible(tile: Tile, layers: ILayer[]) {
|
private updateTileVisible(tile: Tile, layers: ILayer[]) {
|
||||||
this.emitTileVisibleEvent(tile, () => {
|
this.emitTileVisibleEvent(tile, () => {
|
||||||
this.tileLayerManager.updateLayersConfig(
|
updateLayersConfig(layers, 'visible', tile.isVisible);
|
||||||
layers,
|
|
||||||
'visible',
|
|
||||||
tile.isVisible,
|
|
||||||
);
|
|
||||||
this.layerService.reRender();
|
this.layerService.reRender();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,3 +165,18 @@ export function tileAllLoad(tile: Tile, callback: () => void) {
|
||||||
}
|
}
|
||||||
}, 36);
|
}, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateLayersConfig(layers: ILayer[], key: string, value: any) {
|
||||||
|
layers.map((layer) => {
|
||||||
|
if (key === 'mask') {
|
||||||
|
// Tip: 栅格瓦片生效、设置全局的 mask、瓦片被全局的 mask 影响
|
||||||
|
layer.style({
|
||||||
|
mask: value,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
layer.updateLayerConfig({
|
||||||
|
[key]: value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue