mirror of https://gitee.com/antv-l7/antv-l7
Chore tile (#1417)
* fix: 拾取操作 * fix: 文件大小写 * fix: mask map async * fix: remove cancleExtent * fix: rm bottom color * chore: tileLayer 创建机制
This commit is contained in:
parent
605ced75fe
commit
c9a229c821
|
@ -3,8 +3,8 @@ import {
|
|||
Scene,
|
||||
Source,
|
||||
PolygonLayer,
|
||||
LineLayer,
|
||||
TileDebugLayer,
|
||||
// LineLayer,
|
||||
// TileDebugLayer,
|
||||
} from '@antv/l7';
|
||||
// @ts-ignore
|
||||
import { GaodeMap } from '@antv/l7-maps';
|
||||
|
@ -76,22 +76,22 @@ export default () => {
|
|||
}
|
||||
});
|
||||
|
||||
const line = new LineLayer({
|
||||
sourceLayer: 'WLD_L',
|
||||
zIndex: 2,
|
||||
})
|
||||
.source(source)
|
||||
.shape('line')
|
||||
.size(0.6)
|
||||
.color('type', (t) => {
|
||||
if (t === '0') {
|
||||
return 'red';
|
||||
}
|
||||
if (t === '2') {
|
||||
return '#09f';
|
||||
}
|
||||
return '#fc9272';
|
||||
});
|
||||
// const line = new LineLayer({
|
||||
// sourceLayer: 'WLD_L',
|
||||
// zIndex: 2,
|
||||
// })
|
||||
// .source(source)
|
||||
// .shape('line')
|
||||
// .size(0.6)
|
||||
// .color('type', (t) => {
|
||||
// if (t === '0') {
|
||||
// return 'red';
|
||||
// }
|
||||
// if (t === '2') {
|
||||
// return '#09f';
|
||||
// }
|
||||
// return '#fc9272';
|
||||
// });
|
||||
|
||||
water_surface.on('click', (e) => {
|
||||
console.log(e);
|
||||
|
@ -101,9 +101,9 @@ export default () => {
|
|||
console.log(water_surface);
|
||||
});
|
||||
scene.addLayer(water_surface);
|
||||
scene.addLayer(line);
|
||||
const debugerLayer = new TileDebugLayer();
|
||||
scene.addLayer(debugerLayer);
|
||||
// scene.addLayer(line);
|
||||
// const debugerLayer = new TileDebugLayer();
|
||||
// scene.addLayer(debugerLayer);
|
||||
});
|
||||
}, []);
|
||||
return (
|
||||
|
|
|
@ -229,22 +229,13 @@ export interface ITilePickService {
|
|||
}
|
||||
|
||||
|
||||
export interface ITileLayerManager extends IBaseTileLayerManager{
|
||||
tilePickService: ITilePickService;
|
||||
pickLayers(target: IInteractionTarget): boolean;
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
|
||||
export interface IBaseTileLayer {
|
||||
sourceLayer: string;
|
||||
parent: ILayer;
|
||||
tileLayerManager: ITileLayerManager;
|
||||
tilesetManager: TilesetManager | undefined;
|
||||
pickRender(target: IInteractionTarget):void;
|
||||
selectFeature(pickedColors: Uint8Array | undefined):void;
|
||||
highlightPickedFeature(pickedColors: Uint8Array | undefined):void;
|
||||
children: ILayer[];
|
||||
scaleField: any;
|
||||
render(isPicking?: boolean): void;
|
||||
destroy(): void;
|
||||
}
|
||||
|
@ -368,8 +359,6 @@ export interface ILayer {
|
|||
getAttribute(name: string): IStyleAttribute | undefined;
|
||||
getLayerConfig<T>(): Partial<ILayerConfig & ISceneConfig & T>;
|
||||
getLayerAttributeConfig():Partial<ILayerAttributesOption>
|
||||
setBottomColor(color: string): void;
|
||||
getBottomColor(): string;
|
||||
getContainer(): Container;
|
||||
setContainer(container: Container, sceneContainer: Container): void;
|
||||
setCurrentPickId(id: number | null): void;
|
||||
|
|
|
@ -64,6 +64,7 @@ export type IJsonData = IJsonItem[];
|
|||
|
||||
export interface ISource {
|
||||
inited: boolean;
|
||||
isTile: boolean
|
||||
data: IParserData;
|
||||
center: [number, number];
|
||||
parser: IParserCfg;
|
||||
|
|
|
@ -223,9 +223,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
|
||||
private animateStatus: boolean = false;
|
||||
|
||||
// Tip: layer 保底颜色
|
||||
private bottomColor = 'rgba(0, 0, 0, 0)';
|
||||
|
||||
private isDestroyed: boolean = false;
|
||||
|
||||
// private pickingPassRender: IPass<'pixelPicking'>;
|
||||
|
@ -304,14 +301,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
return this.container;
|
||||
}
|
||||
|
||||
public setBottomColor(color: string) {
|
||||
this.bottomColor = color;
|
||||
}
|
||||
|
||||
public getBottomColor() {
|
||||
return this.bottomColor;
|
||||
}
|
||||
|
||||
public addPlugin(plugin: ILayerPlugin): ILayer {
|
||||
this.plugins.push(plugin);
|
||||
return this;
|
||||
|
@ -1312,6 +1301,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
throw new Error('Method not implemented.');
|
||||
}
|
||||
public async rebuildModels() {
|
||||
console.log('2222');
|
||||
await this.buildModels();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
if (layer.layerModelNeedUpdate || !source || !source.inited) {
|
||||
return;
|
||||
}
|
||||
const bottomColor = layer.getBottomColor();
|
||||
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
||||
const filter = styleAttributeService.getLayerStyleAttribute('filter');
|
||||
const { dataArray } = source.data;
|
||||
|
@ -70,7 +69,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// 数据过滤完 再执行数据映射
|
||||
if (filter?.needRemapping && filter?.scale) {
|
||||
filterData = dataArray.filter((record: IParseDataItem) => {
|
||||
return this.applyAttributeMapping(filter, record, bottomColor)[0];
|
||||
return this.applyAttributeMapping(filter, record)[0];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -82,7 +81,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
attributes,
|
||||
filterData,
|
||||
undefined,
|
||||
bottomColor,
|
||||
);
|
||||
layer.setEncodedData(encodeData);
|
||||
filter.needRemapping = false;
|
||||
|
@ -92,7 +90,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
attributesToRemapping,
|
||||
filterData,
|
||||
layer.getEncodedData(),
|
||||
bottomColor,
|
||||
);
|
||||
layer.setEncodedData(encodeData);
|
||||
}
|
||||
|
@ -107,7 +104,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
styleAttributeService,
|
||||
}: { styleAttributeService: IStyleAttributeService },
|
||||
) {
|
||||
const bottomColor = layer.getBottomColor();
|
||||
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
||||
const filter = styleAttributeService.getLayerStyleAttribute('filter');
|
||||
const { dataArray } = layer.getSource().data;
|
||||
|
@ -115,7 +111,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// 数据过滤完 再执行数据映射
|
||||
if (filter?.scale) {
|
||||
filterData = dataArray.filter((record: IParseDataItem) => {
|
||||
return this.applyAttributeMapping(filter, record, bottomColor)[0];
|
||||
return this.applyAttributeMapping(filter, record)[0];
|
||||
});
|
||||
}
|
||||
// Tip: layer 对数据做处理
|
||||
|
@ -123,13 +119,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// 在各个 layer 中继承
|
||||
filterData = layer.processData(filterData);
|
||||
|
||||
const encodeData = this.mapping(
|
||||
layer,
|
||||
attributes,
|
||||
filterData,
|
||||
undefined,
|
||||
bottomColor,
|
||||
);
|
||||
const encodeData = this.mapping(layer, attributes, filterData, undefined);
|
||||
layer.setEncodedData(encodeData);
|
||||
// 对外暴露事件
|
||||
layer.emit('dataUpdate', null);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { ILayer, ILayerPlugin } from '@antv/l7-core';
|
||||
import { injectable } from 'inversify';
|
||||
import 'reflect-metadata';
|
||||
import TileLayer from '../tile/tileLayer/BaseLayer';
|
||||
/**
|
||||
* Layer Model 初始化,更新,销毁
|
||||
*/
|
||||
|
@ -25,6 +26,10 @@ export default class LayerModelPlugin implements ILayerPlugin {
|
|||
|
||||
public apply(layer: ILayer) {
|
||||
layer.hooks.init.tapPromise('LayerModelPlugin', async () => {
|
||||
if (layer.getSource().isTile) {
|
||||
layer.tileLayer = new TileLayer(layer);
|
||||
return;
|
||||
}
|
||||
await this.initLayerModel(layer);
|
||||
});
|
||||
|
||||
|
@ -32,8 +37,13 @@ export default class LayerModelPlugin implements ILayerPlugin {
|
|||
'LayerModelPlugin',
|
||||
async (flag: boolean) => {
|
||||
if (!flag) {
|
||||
// TileLayer 不需要rebuilder
|
||||
return false;
|
||||
}
|
||||
if (layer.getSource().isTile) {
|
||||
layer.tileLayer = new TileLayer(layer);
|
||||
return;
|
||||
}
|
||||
await this.prepareLayerModel(layer);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import TileModel from '../../tile/models/tileModel';
|
||||
import LineModel from '../../line/models/line';
|
||||
import PointExtrudeModel from '../../point/models/extrude';
|
||||
import PointFillModel from '../../point/models/fill';
|
||||
import IMageModel from '../../point/models/image';
|
||||
import NormalModel from '../../point/models/normal';
|
||||
import TextModel from '../../point/models/text';
|
||||
import PolygonTileModel from '../../tile/models/tileModel';
|
||||
import ExtrudeModel from './extrude';
|
||||
import FillModel from './fill';
|
||||
import Ocean from './ocean';
|
||||
|
@ -24,8 +24,8 @@ export type PolygonModelType =
|
|||
| 'ocean'
|
||||
| 'vectorpolygon'
|
||||
| 'tile';
|
||||
|
||||
const PolygonModels: { [key in PolygonModelType]: any } = {
|
||||
vectorpolygon: TileModel,
|
||||
fill: FillModel,
|
||||
line: LineModel,
|
||||
extrude: ExtrudeModel,
|
||||
|
@ -37,7 +37,7 @@ const PolygonModels: { [key in PolygonModelType]: any } = {
|
|||
water: Water,
|
||||
ocean: Ocean,
|
||||
// point_fill: PointModels.fill,
|
||||
vectorpolygon: PolygonTileModel,
|
||||
|
||||
tile: TilePolygonModel,
|
||||
};
|
||||
export default PolygonModels;
|
||||
|
|
|
@ -1,233 +0,0 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
IMapService,
|
||||
IPickingService,
|
||||
IRendererService,
|
||||
ISubLayerInitOptions,
|
||||
ITileLayerManager,
|
||||
ITilePickService,
|
||||
ITileRenderService,
|
||||
ITransform,
|
||||
ScaleAttributeType,
|
||||
} from '@antv/l7-core';
|
||||
import { Base } from './base';
|
||||
import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
|
||||
import { getLayerShape, getMaskValue } from '../utils';
|
||||
import { TileStyleService, ITileStyleService } from '../style/TileStyleService';
|
||||
import { TilePickService } from '../interaction/TilePickService';
|
||||
|
||||
import { TileRenderService } from '../render/TileRenderService';
|
||||
import { styles, IStyles, Attributes } from '../style/constants';
|
||||
import { updateTexture, updateLayersConfig, setStyleAttributeField } from '../style/utils';
|
||||
export class TileLayerManager extends Base implements ITileLayerManager {
|
||||
public tilePickService: ITilePickService;
|
||||
public tileStyleService: ITileStyleService;
|
||||
public tileRenderService: ITileRenderService
|
||||
private transforms: ITransform[];
|
||||
constructor(
|
||||
parent: ILayer,
|
||||
mapService: IMapService,
|
||||
rendererService: IRendererService,
|
||||
pickingService: IPickingService,
|
||||
transforms: ITransform[]
|
||||
) {
|
||||
super();
|
||||
this.parent = parent;
|
||||
this.children = parent.layerChildren;
|
||||
this.mapService = mapService;
|
||||
this.rendererService = rendererService;
|
||||
this.transforms = transforms;
|
||||
|
||||
this.tileRenderService = new TileRenderService(rendererService);
|
||||
|
||||
this.tilePickService = new TilePickService(
|
||||
parent,
|
||||
rendererService,
|
||||
pickingService,
|
||||
this.children,
|
||||
this.tileRenderService
|
||||
);
|
||||
this.tileStyleService = new TileStyleService();
|
||||
|
||||
this.setSubLayerInitOption();
|
||||
this.setConfigListener();
|
||||
this.initTileFactory();
|
||||
}
|
||||
|
||||
public render(): void {
|
||||
this.tileStyleService.checkConfig(this.parent);
|
||||
this.tileRenderService.render(this.children);
|
||||
}
|
||||
|
||||
public pickLayers(target: IInteractionTarget) {
|
||||
return this.tilePickService.pick(this.children, target);
|
||||
}
|
||||
|
||||
private setSubLayerInitOption() {
|
||||
const {
|
||||
zIndex = 0,
|
||||
opacity = 1,
|
||||
mask = false,
|
||||
stroke = '#fff',
|
||||
strokeWidth = 0,
|
||||
strokeOpacity = 1,
|
||||
|
||||
clampLow = true,
|
||||
clampHigh = true,
|
||||
domain = [0, 1],
|
||||
rampColors = {
|
||||
colors: [
|
||||
'rgb(166,97,26)',
|
||||
'rgb(223,194,125)',
|
||||
'rgb(245,245,245)',
|
||||
'rgb(128,205,193)',
|
||||
'rgb(1,133,113)',
|
||||
],
|
||||
positions: [0, 0.25, 0.5, 0.75, 1.0],
|
||||
},
|
||||
featureId = 'id',
|
||||
workerEnabled = false,
|
||||
sourceLayer,
|
||||
|
||||
pixelConstant = 0,
|
||||
pixelConstantR = 256 * 256,
|
||||
pixelConstantG = 256,
|
||||
pixelConstantB = 1,
|
||||
pixelConstantRGB = 0.1,
|
||||
visible,
|
||||
} = this.parent.getLayerConfig() as ISubLayerInitOptions;
|
||||
|
||||
const colorValue = this.tileStyleService.getAttributeScale(
|
||||
this.parent,
|
||||
'color',
|
||||
);
|
||||
const sizeValue = this.tileStyleService.getAttributeScale(
|
||||
this.parent,
|
||||
'size',
|
||||
);
|
||||
const source = this.parent.getSource();
|
||||
const { coords } = source?.data?.tilesetOptions || {};
|
||||
const parentParserType = source.getParserType();
|
||||
|
||||
const layerShape = getLayerShape(this.parent.type, this.parent);
|
||||
|
||||
|
||||
this.initOptions = {
|
||||
visible,
|
||||
layerType: this.parent.type,
|
||||
transforms: this.transforms,
|
||||
shape: layerShape,
|
||||
zIndex,
|
||||
opacity,
|
||||
sourceLayer: this.getSourceLayer(parentParserType, sourceLayer),
|
||||
coords,
|
||||
featureId,
|
||||
color: colorValue,
|
||||
size: sizeValue,
|
||||
mask: getMaskValue(this.parent.type, mask),
|
||||
stroke,
|
||||
strokeWidth,
|
||||
strokeOpacity,
|
||||
// raster tiff
|
||||
clampLow,
|
||||
clampHigh,
|
||||
domain,
|
||||
rampColors,
|
||||
// worker
|
||||
workerEnabled,
|
||||
|
||||
pixelConstant,
|
||||
pixelConstantR,
|
||||
pixelConstantG,
|
||||
pixelConstantB,
|
||||
pixelConstantRGB,
|
||||
};
|
||||
if (rampColors) {
|
||||
// 构建统一的色带贴图
|
||||
const { createTexture2D } = this.rendererService;
|
||||
const imageData = generateColorRamp(rampColors as IColorRamp) as ImageData;
|
||||
const colorTexture = createTexture2D({
|
||||
data: imageData.data,
|
||||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
flipY: false,
|
||||
});
|
||||
this.initOptions.colorTexture = colorTexture;
|
||||
}
|
||||
}
|
||||
|
||||
private getInitOptionValue(field: string) {
|
||||
switch(field) {
|
||||
case 'color': return this.parent.getAttribute('color')?.scale;
|
||||
case 'shape': return this.parent.getAttribute('shape')?.scale;
|
||||
case 'size': return this.parent.getAttribute('size')?.scale;
|
||||
// @ts-ignore
|
||||
default: return this.initOptions[field];
|
||||
}
|
||||
}
|
||||
|
||||
private setInitOptionValue(field: string, value: any) {
|
||||
// @ts-ignore
|
||||
this.initOptions[field] = value;
|
||||
}
|
||||
|
||||
private setConfigListener() {
|
||||
const styleConfigs = styles[this.parent.type as IStyles] || [];
|
||||
styleConfigs.map(style => {
|
||||
this.tileStyleService.setConfig(style, this.getInitOptionValue(style));
|
||||
})
|
||||
|
||||
this.tileStyleService.on('updateConfig', (updateConfigs) => {
|
||||
updateConfigs.map((key: string) => {
|
||||
return this.updateStyle(key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private updateAttribute(style: string) {
|
||||
if(Attributes.includes(style)) {
|
||||
const scaleValue = this.parent.getAttribute(style)?.scale;
|
||||
if (!scaleValue) {
|
||||
return;
|
||||
}
|
||||
this.children.map((child) => {
|
||||
return setStyleAttributeField(
|
||||
child,
|
||||
this.parent,
|
||||
style as ScaleAttributeType,
|
||||
scaleValue,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private updateStyle(style: string) {
|
||||
let updateValue = null;
|
||||
if (Attributes.includes(style)) {
|
||||
this.updateAttribute(style);
|
||||
} else {
|
||||
const layerConfig = this.parent.getLayerConfig() as ISubLayerInitOptions;
|
||||
if (!(style in layerConfig)) {
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
const config = layerConfig[style];
|
||||
updateValue = config;
|
||||
switch(style) {
|
||||
case 'rampColors':
|
||||
const texture = updateTexture(config, this.children, this.rendererService)
|
||||
this.initOptions.colorTexture = texture;
|
||||
break;
|
||||
default:
|
||||
updateLayersConfig(this.children, style, config);
|
||||
}
|
||||
}
|
||||
|
||||
this.setInitOptionValue(style, updateValue);
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.tilePickService.destroy();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { IModelUniform, ITexture2D, IRendererService } from '@antv/l7-core';
|
||||
import BaseModel from '../../core/BaseModel';
|
||||
import { TileLayer } from '../tileLayer/TileLayer';
|
||||
import { MapTileLayer } from '../tileLayer/MapTileLayer';
|
||||
import TileLayer from '../tileLayer/BaseLayer';
|
||||
// import { MapTileLayer } from '../tileLayer/MapTileLayer';
|
||||
import { IColorRamp, generateColorRamp } from '@antv/l7-utils';
|
||||
interface ITileLayerStyleOptions {
|
||||
rampColors?: IColorRamp;
|
||||
|
@ -12,29 +12,16 @@ export default class TileModel extends BaseModel {
|
|||
return {};
|
||||
}
|
||||
|
||||
private getTileLayer(usage?: string) {
|
||||
switch(usage) {
|
||||
case 'basemap':
|
||||
return MapTileLayer;
|
||||
default:
|
||||
return TileLayer;
|
||||
}
|
||||
private getTileLayer() {
|
||||
return TileLayer;
|
||||
}
|
||||
|
||||
public initModels() {
|
||||
const source = this.layer.getSource();
|
||||
this.initTileResource();
|
||||
const { usage } = this.layer.getLayerConfig();
|
||||
if (source?.data.isTile && !this.layer.tileLayer) {
|
||||
const tileLayer = this.getTileLayer(usage);
|
||||
this.layer.tileLayer = new tileLayer({
|
||||
parent: this.layer,
|
||||
rendererService: this.rendererService,
|
||||
mapService: this.mapService,
|
||||
layerService: this.layerService,
|
||||
pickingService: this.pickingService,
|
||||
transforms: source.transforms,
|
||||
});
|
||||
const tileLayer = this.getTileLayer();
|
||||
this.layer.tileLayer = new tileLayer(this.layer);
|
||||
}
|
||||
|
||||
return this.buildModels();
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import {
|
||||
ILayer,
|
||||
IRendererService,
|
||||
ScaleAttributeType,
|
||||
IScaleValue
|
||||
} from '@antv/l7-core';
|
||||
|
||||
import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
|
||||
|
@ -40,34 +38,6 @@ export function updateLayersConfig(layers: ILayer[], key: string, value: any) {
|
|||
});
|
||||
}
|
||||
|
||||
export function setStyleAttributeField(
|
||||
layer: ILayer,
|
||||
parent: ILayer,
|
||||
style: ScaleAttributeType,
|
||||
value: IScaleValue | undefined | string | string[],
|
||||
) {
|
||||
if (Array.isArray(value)) {
|
||||
// @ts-ignore
|
||||
layer[style](...value);
|
||||
return;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
layer[style](value);
|
||||
return;
|
||||
}
|
||||
const defaultValue = getDefaultStyleAttributeField(layer, parent.type, style);
|
||||
if (!value) {
|
||||
layer[style](defaultValue);
|
||||
return layer;
|
||||
}
|
||||
const params = parseScaleValue(value, style);
|
||||
if (params.length === 0) {
|
||||
layer[style](defaultValue);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
layer[style](...params);
|
||||
}
|
||||
}
|
||||
|
||||
export function getDefaultStyleAttributeField(layer: ILayer, type: string, style: string) {
|
||||
switch (style) {
|
||||
|
@ -104,31 +74,3 @@ export function getLayerShape(layerType: string, layer: ILayer) {
|
|||
}
|
||||
}
|
||||
|
||||
export function parseScaleValue(value: IScaleValue | string, type: string) {
|
||||
if (type === 'shape') {
|
||||
if (typeof value === 'string') {
|
||||
return [value];
|
||||
} else if (value?.field) {
|
||||
return [value?.field];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
const { field, values, callback } = value as IScaleValue;
|
||||
if (field && values && Array.isArray(values)) {
|
||||
return [field, values];
|
||||
} else if (field && callback) {
|
||||
return [field, callback];
|
||||
} else if (field) {
|
||||
return [field];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export function setScale(layer: ILayer, parent: ILayer) {
|
||||
const scaleOptions = parent.tileLayer.scaleField;
|
||||
const scaleKeys = Object.keys(scaleOptions);
|
||||
scaleKeys.map((key) => {
|
||||
layer.scale(key, scaleOptions[key]);
|
||||
});
|
||||
}
|
|
@ -12,7 +12,6 @@ export default class DebugTile extends Tile {
|
|||
.size(1)
|
||||
.shape('line')
|
||||
.color('red');
|
||||
console.log(lineLayer)
|
||||
const pointLayer = new PointLayer()
|
||||
.source([pointData],{
|
||||
parser: {
|
||||
|
|
|
@ -9,8 +9,13 @@ export default class VectorTile extends Tile {
|
|||
const vectorLayer = getTileLayer(this.parent.type);
|
||||
const maskLayer = getMaskLayer(this.parent.type);
|
||||
layerOptions.mask = !!maskLayer;
|
||||
|
||||
|
||||
const sourceOptions = this.getSourceOption();
|
||||
if(!sourceOptions){
|
||||
this.isLoaded = true;
|
||||
return
|
||||
}
|
||||
const layer = new vectorLayer({...layerOptions}).source(
|
||||
sourceOptions.data,
|
||||
sourceOptions.options,
|
||||
|
@ -42,14 +47,22 @@ export default class VectorTile extends Tile {
|
|||
|
||||
await this.addLayer(layer);
|
||||
this.isLoaded = true;
|
||||
}
|
||||
// Todo 校验数据有效性
|
||||
protected beforeInit() {
|
||||
|
||||
}
|
||||
protected getSourceOption() {
|
||||
const rawSource = this.parent.getSource();
|
||||
const { sourceLayer, featureId } = this.parent.getLayerConfig<{
|
||||
featureId: string;
|
||||
}>();
|
||||
const features = this.sourceTile.data.layers[sourceLayer as string]
|
||||
.features;
|
||||
|
||||
const vectorLayer = this.sourceTile.data.layers[sourceLayer as string]
|
||||
if(!vectorLayer) {
|
||||
return false
|
||||
}
|
||||
const features = vectorLayer.features;
|
||||
return {
|
||||
data: {
|
||||
type: 'FeatureCollection',
|
||||
|
|
|
@ -1,381 +0,0 @@
|
|||
import {
|
||||
ILayer,
|
||||
IMapService,
|
||||
IParseDataItem,
|
||||
IRendererService,
|
||||
ISubLayerInitOptions,
|
||||
} from '@antv/l7-core';
|
||||
import Source from '@antv/l7-source';
|
||||
import { SourceTile, TilesetManager } from '@antv/l7-utils';
|
||||
import { setStyleAttributeField, setScale } from '../style/utils';
|
||||
import { registerLayers } from '../utils';
|
||||
import { readRasterValue } from '../interaction/getRasterData';
|
||||
import VectorLayer from './layers/vectorLayer';
|
||||
|
||||
import * as turf from '@turf/helpers';
|
||||
import union from '@turf/union';
|
||||
import clone from '@turf/clone';
|
||||
import polygonToLineString from '@turf/polygon-to-line';
|
||||
import {
|
||||
CacheEvent,
|
||||
ILayerTileConfig,
|
||||
ITileFactory,
|
||||
ITileFactoryOptions,
|
||||
ITileStyles,
|
||||
Timeout,
|
||||
} from '../interface';
|
||||
|
||||
type IEvent = { lngLat: {lng: number, lat: number}, x: number, y: number, value: any};
|
||||
|
||||
const EMPTY_FEATURE_DATA = {
|
||||
features: [],
|
||||
featureId: null,
|
||||
vectorTileLayer: null,
|
||||
source: null,
|
||||
};
|
||||
export default class TileFactory implements ITileFactory {
|
||||
public type: string;
|
||||
public parentLayer: ILayer;
|
||||
public mapService: IMapService;
|
||||
public rendererService: IRendererService;
|
||||
public outSideEventTimer: Timeout | null = null;
|
||||
protected zoomOffset: number;
|
||||
protected tilesetManager: TilesetManager;
|
||||
public layers: ILayer[];
|
||||
public loaded: false;
|
||||
// 用于记录图层内事件,辅助判断图层外事件逻辑
|
||||
private eventCache = {
|
||||
click: 0,
|
||||
mousemove: 0,
|
||||
mouseup: 0,
|
||||
mousedown: 0,
|
||||
contextmenu: 0,
|
||||
};
|
||||
constructor(option: ITileFactoryOptions) {
|
||||
this.parentLayer = option.parent;
|
||||
this.mapService = option.mapService;
|
||||
this.rendererService = option.rendererService;
|
||||
|
||||
const source = this.parentLayer.getSource();
|
||||
this.zoomOffset = source.parser.zoomOffset || 0;
|
||||
this.tilesetManager = source.tileset as TilesetManager;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public createTile(tile: SourceTile, initOptions: ISubLayerInitOptions) {
|
||||
return {
|
||||
layers: [] as ILayer[]
|
||||
};
|
||||
}
|
||||
|
||||
public getFeatureData(tile: SourceTile, initOptions: ISubLayerInitOptions) {
|
||||
|
||||
const { sourceLayer, featureId, transforms = [], layerType, shape } = initOptions;
|
||||
if (!sourceLayer) {
|
||||
return EMPTY_FEATURE_DATA;
|
||||
}
|
||||
const vectorTileLayer = tile.data.layers[sourceLayer];
|
||||
const features = vectorTileLayer?.features;
|
||||
if (!(Array.isArray(features) && features.length > 0)) {
|
||||
return EMPTY_FEATURE_DATA;
|
||||
} else {
|
||||
let geofeatures = [];
|
||||
if(layerType === 'LineLayer' && shape === 'simple') {
|
||||
features.map(feature => {
|
||||
|
||||
const cloneFeature = clone(feature);
|
||||
if(cloneFeature.geometry.type === 'MultiPolygon') {
|
||||
// @ts-ignore
|
||||
const linefeatures = polygonToLineString(cloneFeature).features
|
||||
geofeatures.push(...linefeatures)
|
||||
} else if(cloneFeature.geometry.type === 'Polygon') {
|
||||
cloneFeature.geometry.type = 'MultiLineString'
|
||||
geofeatures.push(cloneFeature);
|
||||
} else {
|
||||
geofeatures.push(cloneFeature);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
geofeatures = features;
|
||||
}
|
||||
|
||||
const source = new Source(
|
||||
{
|
||||
type: 'FeatureCollection',
|
||||
features: geofeatures,
|
||||
},
|
||||
{
|
||||
parser: {
|
||||
type: 'geojson',
|
||||
featureId,
|
||||
cancelExtent: true
|
||||
},
|
||||
transforms
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
features: geofeatures,
|
||||
featureId,
|
||||
vectorTileLayer,
|
||||
source,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public createLayer(tileLayerOption: ILayerTileConfig) {
|
||||
const {
|
||||
L7Layer,
|
||||
tile,
|
||||
initOptions,
|
||||
vectorTileLayer,
|
||||
source,
|
||||
needListen = true,
|
||||
} = tileLayerOption;
|
||||
const { mask, color, layerType, size, shape, usage, basemapColor, basemapSize } = initOptions;
|
||||
const FactoryTileLayer = L7Layer ? L7Layer : VectorLayer;
|
||||
const layer = new FactoryTileLayer({
|
||||
|
||||
tileOrigin: vectorTileLayer?.l7TileOrigin,
|
||||
coord: vectorTileLayer?.l7TileCoord,
|
||||
needListen,
|
||||
...this.getLayerInitOption(initOptions),
|
||||
visible: tile.isVisible,
|
||||
});
|
||||
|
||||
if(layerType) layer.type = layerType;
|
||||
// Tip: sign tile layer
|
||||
layer.isTileLayer = true; // vector 、raster
|
||||
|
||||
// vector layer set event
|
||||
if (layer.isVector && usage !== 'basemap') {
|
||||
this.emitEvent([layer]);
|
||||
layer.select(true);
|
||||
}
|
||||
// set source
|
||||
layer.source(source);
|
||||
|
||||
// set scale attribute field
|
||||
setStyleAttributeField(layer, this.parentLayer, 'shape', shape);
|
||||
if(usage !== 'basemap') {
|
||||
// set scale
|
||||
setScale(layer, this.parentLayer);
|
||||
|
||||
setStyleAttributeField(layer, this.parentLayer, 'color', color);
|
||||
setStyleAttributeField(layer, this.parentLayer, 'size', size);
|
||||
} else {
|
||||
layer.style({
|
||||
color: basemapColor,
|
||||
size: basemapSize
|
||||
})
|
||||
}
|
||||
|
||||
// set mask
|
||||
if (mask && layer.isVector) {
|
||||
const masklayer = new VectorLayer({layerType: "MaskLayer"})
|
||||
.source({
|
||||
type: 'FeatureCollection',
|
||||
features: [tile.bboxPolygon],
|
||||
}, {
|
||||
parser: {
|
||||
type: 'geojson',
|
||||
cancelExtent: true
|
||||
}
|
||||
});
|
||||
|
||||
registerLayers(this.parentLayer, [masklayer]);
|
||||
|
||||
layer.addMaskLayer(masklayer);
|
||||
}
|
||||
|
||||
this.layers = [layer];
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public updateStyle(styles: ITileStyles) {
|
||||
return '';
|
||||
}
|
||||
|
||||
protected getTile(lng: number, lat: number) {
|
||||
const zoom = this.mapService.getZoom();
|
||||
return this.tilesetManager.getTileByLngLat(lng, lat, zoom);
|
||||
}
|
||||
|
||||
private bindVectorEvent(layer: ILayer) {
|
||||
layer.on('click', (e) => {
|
||||
this.eventCache.click = 1;
|
||||
this.getFeatureAndEmitEvent('subLayerClick', e);
|
||||
});
|
||||
layer.on('mousemove', (e) => {
|
||||
this.eventCache.mousemove = 1;
|
||||
this.getFeatureAndEmitEvent('subLayerMouseMove', e);
|
||||
});
|
||||
layer.on('mouseenter', (e) => {
|
||||
this.getFeatureAndEmitEvent('subLayerMouseEnter', e);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private readRasterTile(e: IEvent, name: string) {
|
||||
const { lng, lat } = e.lngLat;
|
||||
const tile = this.getTile(lng, lat);
|
||||
if(!tile) return;
|
||||
const data = readRasterValue(tile, this.mapService, e.x, e.y);
|
||||
e.value = data;
|
||||
this.parentLayer.emit(name, e);
|
||||
}
|
||||
|
||||
private bindRasterEvent(layer: ILayer) {
|
||||
layer.on('click', (e) => {
|
||||
this.eventCache.click = 1;
|
||||
this.readRasterTile(e, 'subLayerClick');
|
||||
});
|
||||
layer.on('mousemove', (e) => {
|
||||
this.eventCache.mousemove = 1;
|
||||
this.readRasterTile(e, 'subLayerMouseMove');
|
||||
});
|
||||
layer.on('mouseenter', (e) => {
|
||||
this.readRasterTile(e, 'subLayerMouseMove');
|
||||
});
|
||||
}
|
||||
|
||||
private bindCommonEvent(layer: ILayer) {
|
||||
layer.on('mouseup', (e) => {
|
||||
this.eventCache.mouseup = 1;
|
||||
this.getFeatureAndEmitEvent('subLayerMouseUp', e);
|
||||
});
|
||||
|
||||
layer.on('mouseout', (e) => {
|
||||
this.getFeatureAndEmitEvent('subLayerMouseOut', e);
|
||||
});
|
||||
layer.on('mousedown', (e) => {
|
||||
this.eventCache.mousedown = 1;
|
||||
this.getFeatureAndEmitEvent('subLayerMouseDown', e);
|
||||
});
|
||||
layer.on('contextmenu', (e) => {
|
||||
this.eventCache.contextmenu = 1;
|
||||
this.getFeatureAndEmitEvent('subLayerContextmenu', e);
|
||||
});
|
||||
|
||||
// out side
|
||||
layer.on('unclick', (e) =>
|
||||
this.handleOutsideEvent('click', 'subLayerUnClick', layer, e),
|
||||
);
|
||||
layer.on('unmouseup', (e) =>
|
||||
this.handleOutsideEvent('mouseup', 'subLayerUnMouseUp', layer, e),
|
||||
);
|
||||
layer.on('unmousedown', (e) =>
|
||||
this.handleOutsideEvent('mousedown', 'subLayerUnMouseDown', layer, e),
|
||||
);
|
||||
layer.on('uncontextmenu', (e) =>
|
||||
this.handleOutsideEvent(
|
||||
'contextmenu',
|
||||
'subLayerUnContextmenu',
|
||||
layer,
|
||||
e,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected emitEvent(layers: ILayer[]) {
|
||||
layers.map((layer) => {
|
||||
layer.once('inited', () => {
|
||||
this.bindVectorEvent(layer);
|
||||
|
||||
this.bindCommonEvent(layer);
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected emitRasterEvent(layers: ILayer[]) {
|
||||
layers.map((layer) => {
|
||||
layer.once('inited', () => {
|
||||
|
||||
this.bindRasterEvent(layer);
|
||||
|
||||
this.bindCommonEvent(layer);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected getCombineFeature(features: IParseDataItem[]) {
|
||||
let p: any = null;
|
||||
const properties = features[0];
|
||||
features.map((feature) => {
|
||||
const polygon = turf.polygon(feature.coordinates);
|
||||
if (p === null) {
|
||||
p = polygon;
|
||||
}
|
||||
{
|
||||
p = union(p, polygon);
|
||||
}
|
||||
});
|
||||
if (properties) {
|
||||
p.properties = { ...properties };
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
protected getFeatureAndEmitEvent(
|
||||
eventName: string,
|
||||
e: any,
|
||||
) {
|
||||
const featureId = e.featureId;
|
||||
const features = this.getAllFeatures(featureId);
|
||||
try {
|
||||
e.feature = this.getCombineFeature(features);
|
||||
} catch (err) {
|
||||
console.warn('Combine Featuer Err! Return First Feature!');
|
||||
e.feature = features[0];
|
||||
}
|
||||
|
||||
this.parentLayer.emit(eventName, e);
|
||||
}
|
||||
|
||||
private getAllFeatures(featureId: number) {
|
||||
const allLayers: ILayer[] = this.parentLayer.tileLayer.children;
|
||||
const features: IParseDataItem[] = [];
|
||||
allLayers.map((layer) => {
|
||||
const source = layer.getSource();
|
||||
source.data.dataArray.map((feature) => {
|
||||
if (feature._id === featureId) {
|
||||
features.push(feature);
|
||||
}
|
||||
});
|
||||
});
|
||||
return features;
|
||||
}
|
||||
|
||||
private getLayerInitOption(initOptions: ISubLayerInitOptions) {
|
||||
const option = { ...initOptions };
|
||||
delete option.color;
|
||||
delete option.shape;
|
||||
delete option.size;
|
||||
delete option.coords;
|
||||
delete option.sourceLayer;
|
||||
delete option.coords;
|
||||
return option;
|
||||
}
|
||||
|
||||
private handleOutsideEvent(
|
||||
type: CacheEvent,
|
||||
emitType: string,
|
||||
layer: ILayer,
|
||||
e: any,
|
||||
) {
|
||||
if (this.outSideEventTimer) {
|
||||
clearTimeout(this.outSideEventTimer);
|
||||
this.outSideEventTimer = null;
|
||||
}
|
||||
this.outSideEventTimer = setTimeout(() => {
|
||||
if (this.eventCache[type] > 0) {
|
||||
this.eventCache[type] = 0;
|
||||
} else {
|
||||
this.getFeatureAndEmitEvent(emitType, e);
|
||||
}
|
||||
}, 64);
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
import { ILayer, ISubLayerInitOptions } from '@antv/l7-core';
|
||||
import { SourceTile } from '@antv/l7-utils';
|
||||
import { ITileFactoryOptions } from '../interface';
|
||||
import TileFactory from './base';
|
||||
import VectorLayer from './layers/vectorLayer';
|
||||
|
||||
export default class TestTile extends TileFactory {
|
||||
public parentLayer: ILayer;
|
||||
|
||||
constructor(option: ITileFactoryOptions) {
|
||||
super(option);
|
||||
this.parentLayer = option.parent;
|
||||
}
|
||||
|
||||
public createTile(tile: SourceTile, initOptions: ISubLayerInitOptions) {
|
||||
const { sourceLayer } = initOptions;
|
||||
if (!sourceLayer) {
|
||||
return {
|
||||
layers: [],
|
||||
};
|
||||
}
|
||||
const vectorTileLayer = tile.data.layers[sourceLayer];
|
||||
const features = vectorTileLayer?.features;
|
||||
if (features.length === 0) {
|
||||
return {
|
||||
layers: [],
|
||||
};
|
||||
}
|
||||
|
||||
const properties = features[0].properties;
|
||||
|
||||
const text = new VectorLayer({
|
||||
layerType: 'PointLayer',
|
||||
minZoom: tile.z -1,
|
||||
maxZoom: tile.z +1,
|
||||
usage: 'basemap',
|
||||
needListen: false
|
||||
})
|
||||
.source([properties], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'textLng',
|
||||
y: 'textLat',
|
||||
}
|
||||
})
|
||||
.shape(`${tile.x}/${tile.y}/${tile.z}`)
|
||||
.style({
|
||||
size: 20,
|
||||
color: '#000',
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2
|
||||
});
|
||||
|
||||
const line = new VectorLayer({ layerType: 'LineLayer', usage: 'basemap', needListen: false })
|
||||
.source({
|
||||
type: 'FeatureCollection',
|
||||
features: features,
|
||||
}, {
|
||||
parser: {
|
||||
type: 'geojson',
|
||||
}
|
||||
})
|
||||
.shape('simple')
|
||||
.style({
|
||||
color: '#f00'
|
||||
});
|
||||
|
||||
return {
|
||||
layers: [line,text],
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
import { ILayer, ISubLayerInitOptions } from '@antv/l7-core';
|
||||
import Source from '@antv/l7-source';
|
||||
import { SourceTile } from '@antv/l7-utils';
|
||||
import { ITileFactoryOptions } from '../interface';
|
||||
import TileFactory from './base';
|
||||
|
||||
export default class VectorMaskTile extends TileFactory {
|
||||
public parentLayer: ILayer;
|
||||
|
||||
constructor(option: ITileFactoryOptions) {
|
||||
super(option);
|
||||
this.parentLayer = option.parent;
|
||||
}
|
||||
|
||||
public createTile(tile: SourceTile, initOptions: ISubLayerInitOptions) {
|
||||
const { features, vectorTileLayer, source } = this.getFeatureData(
|
||||
tile,
|
||||
initOptions,
|
||||
);
|
||||
if (features.length === 0) {
|
||||
return {
|
||||
layers: [],
|
||||
};
|
||||
}
|
||||
const layer = this.createLayer({
|
||||
tile,
|
||||
initOptions,
|
||||
vectorTileLayer,
|
||||
source: source as Source,
|
||||
needListen: false
|
||||
});
|
||||
return {
|
||||
layers: [layer],
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
import { ILayer, ISubLayerInitOptions } from '@antv/l7-core';
|
||||
import Source from '@antv/l7-source';
|
||||
import { SourceTile } from '@antv/l7-utils';
|
||||
import ImageLayer from '../../image';
|
||||
import { ITileFactoryOptions } from '../interface';
|
||||
import TileFactory from './base';
|
||||
|
||||
export default class RasterTile extends TileFactory {
|
||||
public parentLayer: ILayer;
|
||||
constructor(option: ITileFactoryOptions) {
|
||||
super(option);
|
||||
this.parentLayer = option.parent;
|
||||
}
|
||||
|
||||
public createTile(tile: SourceTile, initOptions: ISubLayerInitOptions) {
|
||||
const source = new Source(tile.data, {
|
||||
parser: {
|
||||
type: 'image',
|
||||
extent: tile.bounds,
|
||||
},
|
||||
});
|
||||
|
||||
const layer = this.createLayer({
|
||||
L7Layer: ImageLayer,
|
||||
tile,
|
||||
initOptions,
|
||||
source,
|
||||
});
|
||||
return {
|
||||
layers: [layer],
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import { ILayer, ISubLayerInitOptions } from '@antv/l7-core';
|
||||
import { SourceTile } from '@antv/l7-utils';
|
||||
import { ITileFactoryOptions } from '../interface';
|
||||
import TileFactory from './base';
|
||||
import RasterDataLayer from './layers/rasterDataLayer';
|
||||
|
||||
export default class RasterTiffTile extends TileFactory {
|
||||
public parentLayer: ILayer;
|
||||
|
||||
constructor(option: ITileFactoryOptions) {
|
||||
super(option);
|
||||
this.parentLayer = option.parent;
|
||||
}
|
||||
|
||||
public createTile(tile: SourceTile, initOptions: ISubLayerInitOptions) {
|
||||
const {
|
||||
colorTexture,
|
||||
opacity,
|
||||
domain,
|
||||
clampHigh,
|
||||
clampLow,
|
||||
mask,
|
||||
} = initOptions;
|
||||
const rasterData = tile.data;
|
||||
if (!rasterData.data) {
|
||||
console.warn('raster data not exist!');
|
||||
return {
|
||||
layers: [],
|
||||
};
|
||||
}
|
||||
const dataType = this.parentLayer?.getSource()?.parser?.dataType;
|
||||
const layer = new RasterDataLayer({
|
||||
visible: tile.isVisible,
|
||||
mask,
|
||||
})
|
||||
.source(rasterData.data, {
|
||||
parser: {
|
||||
// 数据栅格分为单通道栅格和多通道彩色栅格
|
||||
type: dataType === 'rgb' ? 'rasterRgb': 'raster',
|
||||
width: rasterData.width,
|
||||
height: rasterData.height,
|
||||
extent: tile.bboxPolygon.bbox,
|
||||
},
|
||||
})
|
||||
.style({
|
||||
colorTexture,
|
||||
opacity,
|
||||
domain,
|
||||
clampHigh,
|
||||
clampLow,
|
||||
});
|
||||
this.emitRasterEvent([layer]);
|
||||
return {
|
||||
layers: [layer],
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
import { ILayer, ISubLayerInitOptions } from '@antv/l7-core';
|
||||
import Source from '@antv/l7-source';
|
||||
import { SourceTile } from '@antv/l7-utils';
|
||||
import { ITileFactoryOptions } from '../interface';
|
||||
import TileFactory from './base';
|
||||
export default class VectorTile extends TileFactory {
|
||||
public parentLayer: ILayer;
|
||||
|
||||
constructor(option: ITileFactoryOptions) {
|
||||
super(option);
|
||||
this.parentLayer = option.parent;
|
||||
}
|
||||
|
||||
public createTile(tile: SourceTile, initOptions: ISubLayerInitOptions) {
|
||||
const { features, vectorTileLayer, source } = this.getFeatureData(
|
||||
tile,
|
||||
initOptions,
|
||||
);
|
||||
if (features.length === 0) {
|
||||
return {
|
||||
layers: [],
|
||||
};
|
||||
}
|
||||
|
||||
const layer = this.createLayer({
|
||||
tile,
|
||||
initOptions,
|
||||
vectorTileLayer,
|
||||
source: source as Source,
|
||||
});
|
||||
return {
|
||||
layers: [layer],
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,32 +1,75 @@
|
|||
import { ILayer, IMapService, ILayerService, ISource,IInteractionTarget } from '@antv/l7-core';
|
||||
import {
|
||||
ILayer,
|
||||
IMapService,
|
||||
ILayerService,
|
||||
IRendererService,
|
||||
TYPES,
|
||||
ISource,
|
||||
IPickingService,
|
||||
IInteractionTarget
|
||||
} from '@antv/l7-core';
|
||||
import { SourceTile, TilesetManager } from '@antv/l7-utils';
|
||||
import { debounce } from 'lodash';
|
||||
import { TileLayerService } from '../service/TileLayerService';
|
||||
import { TilePickService } from '../service/TilePickService';
|
||||
import { debounce } from 'lodash';
|
||||
import { getTileFactory } from '../tileFactory'
|
||||
|
||||
export class Base {
|
||||
public tileLayerManager: any;
|
||||
export default class BaseTileLayer {
|
||||
private parent: ILayer;
|
||||
public tileLayerService: TileLayerService;
|
||||
public get children() {
|
||||
return this.tileLayerManager.children;
|
||||
}
|
||||
public sourceLayer: string;
|
||||
public parent: ILayer;
|
||||
public initedTileset: boolean = false; // 瓦片是否加载成功
|
||||
|
||||
public tilesetManager: TilesetManager | undefined; // 瓦片数据管理器
|
||||
public scaleField: any;
|
||||
|
||||
protected mapService: IMapService;
|
||||
protected layerService: ILayerService;
|
||||
protected tilePickService: TilePickService
|
||||
protected rendererService: IRendererService;
|
||||
protected pickingService:IPickingService;
|
||||
protected tilePickService: TilePickService;
|
||||
public tilesetManager: TilesetManager; // 瓦片数据管理器
|
||||
public initedTileset: boolean = false; // 瓦片是否加载成功
|
||||
|
||||
protected lastViewStates: {
|
||||
zoom: number;
|
||||
latLonBounds: [number, number, number, number];
|
||||
};
|
||||
|
||||
constructor(parent: ILayer) {
|
||||
this.parent = parent;
|
||||
const container = this.parent.getContainer();
|
||||
this.rendererService = container.get<IRendererService>(
|
||||
TYPES.IRendererService,
|
||||
);
|
||||
this.layerService = container.get<ILayerService>(TYPES.ILayerService);
|
||||
this.mapService = container.get<IMapService>(TYPES.IMapService);
|
||||
this.pickingService = container.get<IPickingService>(
|
||||
TYPES.IPickingService,
|
||||
);
|
||||
|
||||
// 初始化瓦片管理服务
|
||||
this.tileLayerService = new TileLayerService({
|
||||
rendererService: this.rendererService,
|
||||
layerService:this.layerService,
|
||||
parent
|
||||
})
|
||||
// 初始化拾取服务
|
||||
this.tilePickService = new TilePickService({
|
||||
tileLayerService: this.tileLayerService,
|
||||
layerService:this.layerService,
|
||||
})
|
||||
|
||||
this.initTileSetManager();
|
||||
|
||||
}
|
||||
|
||||
protected initTileSetManager() {
|
||||
const source: ISource = this.parent.getSource();
|
||||
this.tilesetManager = source.tileset as TilesetManager;
|
||||
|
||||
if (!this.initedTileset) {
|
||||
this.bindTilesetEvent();
|
||||
this.initedTileset = true;
|
||||
}
|
||||
|
||||
const { latLonBounds, zoom } = this.getCurrentView();
|
||||
this.tilesetManager?.update(zoom, latLonBounds);
|
||||
}
|
||||
protected mapchange() {
|
||||
const { latLonBounds, zoom } = this.getCurrentView();
|
||||
|
||||
|
@ -52,7 +95,6 @@ export class Base {
|
|||
|
||||
this.tilesetManager?.throttleUpdate(zoom, latLonBounds);
|
||||
}
|
||||
|
||||
protected getCurrentView() {
|
||||
const bounds = this.mapService.getBounds();
|
||||
const latLonBounds: [number, number, number, number] = [
|
||||
|
@ -66,23 +108,7 @@ export class Base {
|
|||
return { latLonBounds, zoom };
|
||||
}
|
||||
|
||||
protected initTileSetManager() {
|
||||
const source: ISource = this.parent.getSource();
|
||||
this.tilesetManager = source.tileset as TilesetManager;
|
||||
|
||||
if (!this.initedTileset) {
|
||||
this.bindTilesetEvent();
|
||||
this.initedTileset = true;
|
||||
}
|
||||
|
||||
const { latLonBounds, zoom } = this.getCurrentView();
|
||||
this.tilesetManager?.update(zoom, latLonBounds);
|
||||
}
|
||||
|
||||
private bindTilesetEvent() {
|
||||
if (!this.tilesetManager) {
|
||||
return;
|
||||
}
|
||||
// 瓦片数据加载成功
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
this.tilesetManager.on('tile-loaded', (tile: SourceTile) => {
|
||||
|
@ -111,7 +137,7 @@ export class Base {
|
|||
this.mapService.on('zoomend', () => this.mapchange());
|
||||
this.mapService.on('moveend', () => this.viewchange());
|
||||
}
|
||||
|
||||
|
||||
public render() {
|
||||
this.tileLayerService.render();
|
||||
}
|
||||
|
@ -150,6 +176,10 @@ export class Base {
|
|||
const tileInstance = getTileFactory(this.parent);
|
||||
const tileLayer = new tileInstance(tile, this.parent);
|
||||
await tileLayer.initTileLayer();
|
||||
if(tileLayer.getLayers().length!==0) {
|
||||
this.tileLayerService.addTile(tileLayer);
|
||||
this.layerService.reRender()
|
||||
}
|
||||
this.tileLayerService.addTile(tileLayer);
|
||||
this.layerService.reRender()
|
||||
} else {
|
||||
|
@ -166,14 +196,15 @@ export class Base {
|
|||
}
|
||||
|
||||
public isTileReady(tile: SourceTile) {
|
||||
if (tile.data?.layers && this.sourceLayer) {
|
||||
// vector
|
||||
const vectorTileLayer = tile.data.layers[this.sourceLayer];
|
||||
const features = vectorTileLayer?.features;
|
||||
if (!(Array.isArray(features) && features.length > 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if (tile.data?.layers && this.sourceLayer) {
|
||||
// // vector
|
||||
// const vectorTileLayer = tile.data.layers[this.sourceLayer];
|
||||
// const features = vectorTileLayer?.features;
|
||||
// if (!(Array.isArray(features) && features.length > 0)) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
import {
|
||||
IBaseTileLayer,
|
||||
ITileLayerOPtions,
|
||||
// IBaseTileLayerManager,
|
||||
} from '@antv/l7-core';
|
||||
import { BaseMapTileLayerManager } from '../manager/mapLayerManager';
|
||||
|
||||
import { Base } from './base';
|
||||
|
||||
export class MapTileLayer extends Base implements IBaseTileLayer {
|
||||
// public tileLayerManager: IBaseTileLayerManager;
|
||||
constructor({
|
||||
parent,
|
||||
rendererService,
|
||||
mapService,
|
||||
layerService,
|
||||
}: ITileLayerOPtions) {
|
||||
super();
|
||||
const parentSource = parent.getSource();
|
||||
const { sourceLayer } =
|
||||
parentSource?.data?.tilesetOptions || {};
|
||||
this.sourceLayer = sourceLayer;
|
||||
this.parent = parent;
|
||||
this.mapService = mapService;
|
||||
this.layerService = layerService;
|
||||
|
||||
this.tileLayerManager = new BaseMapTileLayerManager(
|
||||
parent,
|
||||
mapService,
|
||||
rendererService,
|
||||
);
|
||||
|
||||
this.initTileSetManager();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ITileLayer,
|
||||
ITileLayerManager,
|
||||
ITileLayerOPtions,
|
||||
} from '@antv/l7-core';
|
||||
import { TileLayerService } from '../service/TileLayerService';
|
||||
import { TilePickService } from '../service/TilePickService'
|
||||
import { Base } from './base';
|
||||
|
||||
import { setSelect, setHighlight, setPickState, clearPickState } from '../interaction/utils';
|
||||
|
||||
|
||||
export class TileLayer extends Base implements ITileLayer {
|
||||
public get children() {
|
||||
return this.tileLayerManager.children;
|
||||
}
|
||||
public tileLayerManager: ITileLayerManager;
|
||||
public tilePickService:TilePickService;
|
||||
|
||||
|
||||
private pickColors: {
|
||||
select: any;
|
||||
active: any;
|
||||
} = {
|
||||
select: null,
|
||||
active: null,
|
||||
};
|
||||
|
||||
constructor({
|
||||
parent,
|
||||
rendererService,
|
||||
mapService,
|
||||
layerService,
|
||||
}: ITileLayerOPtions) {
|
||||
super();
|
||||
|
||||
this.sourceLayer = parent.getLayerConfig()?.sourceLayer as string;
|
||||
|
||||
this.parent = parent;
|
||||
this.mapService = mapService;
|
||||
this.layerService = layerService;
|
||||
// 初始化瓦片管理服务
|
||||
this.tileLayerService = new TileLayerService({
|
||||
rendererService,
|
||||
layerService,
|
||||
parent
|
||||
})
|
||||
// 初始化拾取服务
|
||||
this.tilePickService = new TilePickService({
|
||||
tileLayerService: this.tileLayerService,
|
||||
layerService,
|
||||
})
|
||||
|
||||
// this.tileLayerManager = new TileLayerManager(
|
||||
// parent,
|
||||
// mapService,
|
||||
// rendererService,
|
||||
// pickingService,
|
||||
// transforms
|
||||
// );
|
||||
|
||||
this.initTileSetManager();
|
||||
// this.bindSubLayerEvent();
|
||||
// this.bindSubLayerPick();
|
||||
|
||||
// this.scaleField = this.parent.getScaleOptions();
|
||||
}
|
||||
|
||||
public clearPick(type: string) {
|
||||
// Tip: 瓦片只有在 mousemove 的时候需要设置清除
|
||||
if (type === 'mousemove') {
|
||||
this.tileLayerManager.tilePickService.clearPick();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除 select 的选中状态
|
||||
*/
|
||||
public clearPickState() {
|
||||
clearPickState(this.children)
|
||||
}
|
||||
|
||||
/**
|
||||
* 瓦片图层独立的拾取逻辑
|
||||
* @param target
|
||||
* @returns
|
||||
*/
|
||||
public pickLayers(target: IInteractionTarget) {
|
||||
return this.tileLayerManager.pickLayers(target);
|
||||
}
|
||||
|
||||
public setPickState(layers: ILayer[]) {
|
||||
setPickState(layers, this.pickColors);
|
||||
}
|
||||
|
||||
|
||||
private bindSubLayerPick() {
|
||||
this.tileLayerManager.tilePickService.on('pick', (e) => {
|
||||
// @ts-ignore
|
||||
const [r, g, b] = e.pickedColors;
|
||||
|
||||
if (e.type === 'click') {
|
||||
const restLayers = this.children
|
||||
.filter(
|
||||
(child) => child.inited && child.isVisible() && child.isVector,
|
||||
)
|
||||
.filter((child) => child !== e.layer);
|
||||
|
||||
const renderList = this.layerService.getRenderList();
|
||||
const color = setSelect(restLayers, [r, g, b], renderList)
|
||||
this.pickColors.select = color;
|
||||
} else {
|
||||
setHighlight(this.children, [r, g, b]);
|
||||
this.pickColors.active = [r, g, b];
|
||||
}
|
||||
});
|
||||
|
||||
this.tileLayerManager.tilePickService.on('unpick', () => {
|
||||
this.pickColors.active = null;
|
||||
});
|
||||
}
|
||||
|
||||
protected bindSubLayerEvent() {
|
||||
/**
|
||||
* layer.on('click', (ev) => {}); // 鼠标左键点击图层事件
|
||||
* layer.on('mouseenter', (ev) => {}); // 鼠标进入图层要素
|
||||
* layer.on('mousemove', (ev) => {}); // 鼠标在图层上移动时触发
|
||||
* layer.on('mouseout', (ev) => {}); // 鼠标移出图层要素时触发
|
||||
* layer.on('mouseup', (ev) => {}); // 鼠标在图层上单击抬起时触发
|
||||
* layer.on('mousedown', (ev) => {}); // 鼠标在图层上单击按下时触发
|
||||
* layer.on('contextmenu', (ev) => {}); // 图层要素点击右键菜单
|
||||
*
|
||||
* 鼠标在图层外的事件
|
||||
* layer.on('unclick', (ev) => {}); // 图层外点击
|
||||
* layer.on('unmousemove', (ev) => {}); // 图层外移动
|
||||
* layer.on('unmouseup', (ev) => {}); // 图层外鼠标抬起
|
||||
* layer.on('unmousedown', (ev) => {}); // 图层外单击按下时触发
|
||||
* layer.on('uncontextmenu', (ev) => {}); // 图层外点击右键
|
||||
* layer.on('unpick', (ev) => {}); // 图层外的操作的所有事件
|
||||
*/
|
||||
this.parent.on('subLayerClick', (e) => {
|
||||
this.parent.emit('click', { ...e });
|
||||
});
|
||||
this.parent.on('subLayerMouseMove', (e) =>
|
||||
this.parent.emit('mousemove', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerMouseUp', (e) =>
|
||||
this.parent.emit('mouseup', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerMouseEnter', (e) =>
|
||||
this.parent.emit('mouseenter', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerMouseOut', (e) =>
|
||||
this.parent.emit('mouseout', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerMouseDown', (e) =>
|
||||
this.parent.emit('mousedown', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerContextmenu', (e) =>
|
||||
this.parent.emit('contextmenu', { ...e }),
|
||||
);
|
||||
|
||||
// vector layer 图层外事件
|
||||
this.parent.on('subLayerUnClick', (e) =>
|
||||
this.parent.emit('unclick', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerUnMouseMove', (e) =>
|
||||
this.parent.emit('unmousemove', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerUnMouseUp', (e) =>
|
||||
this.parent.emit('unmouseup', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerUnMouseDown', (e) =>
|
||||
this.parent.emit('unmousedown', { ...e }),
|
||||
);
|
||||
this.parent.on('subLayerUnContextmenu', (e) =>
|
||||
this.parent.emit('uncontextmenu', { ...e }),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from '@antv/l7-core';
|
||||
import { Version } from '@antv/l7-maps';
|
||||
import Source from '@antv/l7-source';
|
||||
import { isColor, normalize, rgb2arr } from '@antv/l7-utils';
|
||||
import { normalize, rgb2arr } from '@antv/l7-utils';
|
||||
import { ILineLayerStyleOptions } from '../core/interface';
|
||||
import { cloneDeep } from 'lodash';
|
||||
|
||||
|
@ -121,7 +121,6 @@ function unProjectCoordinates(coordinates: any, mapService: IMapService) {
|
|||
function applyAttributeMapping(
|
||||
attribute: IStyleAttribute,
|
||||
record: { [key: string]: unknown },
|
||||
minimumColor?: string,
|
||||
) {
|
||||
if (!attribute.scale) {
|
||||
return [];
|
||||
|
@ -137,9 +136,7 @@ function applyAttributeMapping(
|
|||
});
|
||||
|
||||
const mappingResult = attribute.mapping ? attribute.mapping(params) : [];
|
||||
if (attribute.name === 'color' && !isColor(mappingResult[0])) {
|
||||
return [minimumColor];
|
||||
}
|
||||
|
||||
return mappingResult;
|
||||
}
|
||||
|
||||
|
@ -148,7 +145,6 @@ function mapping(
|
|||
data: IParseDataItem[],
|
||||
fontService: IFontService,
|
||||
mapService: IMapService,
|
||||
minimumColor?: string,
|
||||
layer?: ILayer,
|
||||
): IEncodeFeature[] {
|
||||
const {
|
||||
|
@ -165,7 +161,7 @@ function mapping(
|
|||
attributes
|
||||
.filter((attribute) => attribute.scale !== undefined)
|
||||
.forEach((attribute: IStyleAttribute) => {
|
||||
let values = applyAttributeMapping(attribute, record, minimumColor);
|
||||
let values = applyAttributeMapping(attribute, record);
|
||||
|
||||
attribute.needRemapping = false;
|
||||
|
||||
|
@ -213,7 +209,6 @@ export function calculateData(
|
|||
options: ISourceCFG | undefined,
|
||||
): IEncodeFeature[] {
|
||||
const source = new Source(data, options);
|
||||
const bottomColor = layer.getBottomColor();
|
||||
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
||||
const { dataArray } = source.data;
|
||||
const filterData = dataArray;
|
||||
|
@ -223,7 +218,6 @@ export function calculateData(
|
|||
filterData,
|
||||
fontService,
|
||||
mapService,
|
||||
bottomColor,
|
||||
layer,
|
||||
);
|
||||
source.destroy();
|
||||
|
|
|
@ -31,9 +31,10 @@ function mergeCustomizer(objValue: any, srcValue: any) {
|
|||
return srcValue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
export default class Source extends EventEmitter implements ISource {
|
||||
public type: string = 'source';
|
||||
public isTile: boolean = false;
|
||||
public inited: boolean = false;
|
||||
public data: IParserData;
|
||||
public center: [number, number];
|
||||
|
@ -301,6 +302,7 @@ export default class Source extends EventEmitter implements ISource {
|
|||
if (!tilesetOptions) {
|
||||
return;
|
||||
}
|
||||
this.isTile = true;
|
||||
if (this.tileset) {
|
||||
this.tileset.updateOptions(tilesetOptions);
|
||||
return this.tileset;
|
||||
|
|
|
@ -234,13 +234,4 @@ export default class ThreeJSLayer
|
|||
public addAnimateMixer(mixer: AnimationMixer) {
|
||||
this.animateMixer.push(mixer);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public setBottomColor(color: string): void {
|
||||
console.warn('empty function');
|
||||
}
|
||||
|
||||
public getBottomColor() {
|
||||
return 'rgba(0, 0, 0, 0)';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue