fix: 修复图层高亮不正常显示的问题 fix #150

This commit is contained in:
thinkinggis 2020-01-15 15:11:33 +08:00
parent d24a842e72
commit f5c6f74ab7
12 changed files with 45 additions and 80 deletions

View File

@ -33,6 +33,5 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/ZVfOvhVCzwBkISNsuKCc.json')
].reverse(), ].reverse(),
) )
scene.addLayer(layer); scene.addLayer(layer);
console.log(layer);
}); });

View File

@ -56,10 +56,10 @@ const defaultLayerConfig: Partial<ILayerConfig> = {
enableMultiPassRenderer: true, enableMultiPassRenderer: true,
enablePicking: true, enablePicking: true,
active: false, active: false,
activeColor: 'red', activeColor: '#2f54eb',
enableHighlight: false, enableHighlight: false,
enableSelect: false, enableSelect: false,
highlightColor: 'red', highlightColor: '#2f54eb',
selectColor: 'blue', selectColor: 'blue',
enableTAA: false, enableTAA: false,
jitterScale: 1, jitterScale: 1,

View File

@ -127,7 +127,7 @@ export interface ILayer {
id: number | { x: number; y: number }, id: number | { x: number; y: number },
option?: IActiveOption, option?: IActiveOption,
): void; ): void;
select(option: IActiveOption | false): ILayer; select(option: IActiveOption | boolean): ILayer;
setSelect( setSelect(
id: number | { x: number; y: number }, id: number | { x: number; y: number },
option?: IActiveOption, option?: IActiveOption,

View File

@ -16,6 +16,8 @@ export default class LayerService implements ILayerService {
private animateInstanceCount: number = 0; private animateInstanceCount: number = 0;
private alreadyInRendering: boolean = false;
@inject(TYPES.IRendererService) @inject(TYPES.IRendererService)
private readonly renderService: IRendererService; private readonly renderService: IRendererService;
@ -58,7 +60,11 @@ export default class LayerService implements ILayerService {
public renderLayers() { public renderLayers() {
// TODO脏检查只渲染发生改变的 Layer // TODO脏检查只渲染发生改变的 Layer
if (this.alreadyInRendering) {
return;
}
// //
this.alreadyInRendering = true;
this.clear(); this.clear();
this.layers this.layers
.filter((layer) => layer.isVisible()) .filter((layer) => layer.isVisible())
@ -69,6 +75,7 @@ export default class LayerService implements ILayerService {
layer.render(); layer.render();
layer.hooks.afterRender.call(); layer.hooks.afterRender.call();
}); });
this.alreadyInRendering = false;
} }
public updateRenderOrder() { public updateRenderOrder() {

View File

@ -237,59 +237,14 @@ export default class PixelPickingPass<
*/ */
private highlightPickedFeature(pickedColors: Uint8Array | undefined) { private highlightPickedFeature(pickedColors: Uint8Array | undefined) {
const [r, g, b] = pickedColors; const [r, g, b] = pickedColors;
const { clear, useFramebuffer } = this.rendererService; this.layer.hooks.beforeHighlight.call([r, g, b]);
// 先输出到 PostProcessor this.layerService.renderLayers();
const readFBO = this.layer.multiPassRenderer
.getPostProcessor()
.getReadFBO();
this.layer.hooks.beforeRender.call();
useFramebuffer(readFBO, () => {
clear({
color: [0, 0, 0, 0],
depth: 1,
stencil: 0,
framebuffer: readFBO,
});
// TODO: highlight pass 需要 multipass
const originRenderFlag = this.layer.multiPassRenderer.getRenderFlag();
this.layer.multiPassRenderer.setRenderFlag(false);
this.layer.hooks.beforeHighlight.call([r, g, b]);
this.layer.render();
this.layer.hooks.afterHighlight.call();
this.layer.hooks.afterRender.call();
this.layer.multiPassRenderer.setRenderFlag(originRenderFlag);
});
this.layer.multiPassRenderer.getPostProcessor().render(this.layer);
} }
private selectFeature(pickedColors: Uint8Array | undefined) { private selectFeature(pickedColors: Uint8Array | undefined) {
const [r, g, b] = pickedColors; const [r, g, b] = pickedColors;
const { clear, useFramebuffer } = this.rendererService; this.layer.hooks.beforeSelect.call([r, g, b]);
this.layerService.renderLayers();
// 先输出到 PostProcessor
const readFBO = this.layer.multiPassRenderer
.getPostProcessor()
.getReadFBO();
this.layer.hooks.beforeRender.call();
useFramebuffer(readFBO, () => {
clear({
color: [0, 0, 0, 0],
depth: 1,
stencil: 0,
framebuffer: readFBO,
});
// TODO: highlight pass 需要 multipass
const originRenderFlag = this.layer.multiPassRenderer.getRenderFlag();
this.layer.multiPassRenderer.setRenderFlag(false);
this.layer.hooks.beforeSelect.call([r, g, b]);
this.layer.render();
this.layer.hooks.afterSelect.call();
this.layer.hooks.afterRender.call();
this.layer.multiPassRenderer.setRenderFlag(originRenderFlag);
});
this.layer.multiPassRenderer.getPostProcessor().render(this.layer);
} }
private selectFeatureHander({ featureId }: Partial<IInteractionTarget>) { private selectFeatureHander({ featureId }: Partial<IInteractionTarget>) {

View File

@ -43,4 +43,4 @@ vec4 filterPickingColor(vec4 color) {
*/ */
vec4 filterColor(vec4 color) { vec4 filterColor(vec4 color) {
return filterPickingColor(filterHighlightColor(color)); return filterPickingColor(filterHighlightColor(color));
} }

View File

@ -38,6 +38,7 @@ import {
TYPES, TYPES,
} from '@antv/l7-core'; } from '@antv/l7-core';
import Source from '@antv/l7-source'; import Source from '@antv/l7-source';
import { encodePickingColor } from '@antv/l7-utils';
import { EventEmitter } from 'eventemitter3'; import { EventEmitter } from 'eventemitter3';
import { Container } from 'inversify'; import { Container } from 'inversify';
import { isFunction, isObject } from 'lodash'; import { isFunction, isObject } from 'lodash';
@ -509,7 +510,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
} }
} }
public select(option: IActiveOption | false): ILayer { public select(option: IActiveOption | boolean): ILayer {
const activeOption: Partial<ILayerConfig> = {}; const activeOption: Partial<ILayerConfig> = {};
activeOption.enableSelect = isObject(option) ? true : option; activeOption.enableSelect = isObject(option) ? true : option;
if (isObject(option)) { if (isObject(option)) {
@ -518,7 +519,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
activeOption.selectColor = option.color; activeOption.selectColor = option.color;
} }
} else { } else {
activeOption.enableHighlight = !!option; activeOption.enableSelect = !!option;
} }
this.updateLayerConfig(activeOption); this.updateLayerConfig(activeOption);
return this; return this;
@ -543,7 +544,11 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
? options.color ? options.color
: this.getLayerConfig().selectColor, : this.getLayerConfig().selectColor,
}); });
this.interactionService.triggerSelect(id); this.hooks.beforeHighlight.call(
encodePickingColor(id as number) as number[],
);
// this.interactionService.triggerSelect(id);
// this.reRender();
} }
} }
public setBlend(type: keyof typeof BlendType): void { public setBlend(type: keyof typeof BlendType): void {

View File

@ -15,19 +15,5 @@ export default class LayerStylePlugin implements ILayerPlugin {
layer.fitBounds(); layer.fitBounds();
} }
}); });
layer.hooks.beforeRender.tap('LayerStylePlugin', () => {
const {
highlightColor = 'red',
pickedFeatureID = -1,
} = layer.getLayerConfig();
layer.models.forEach((model) =>
model.addUniforms({
u_PickingStage: 2.0,
u_PickingColor: encodePickingColor(pickedFeatureID),
u_HighlightColor: rgb2arr(highlightColor as string),
}),
);
});
} }
} }

View File

@ -7,7 +7,11 @@ import {
IRendererService, IRendererService,
IStyleAttributeService, IStyleAttributeService,
} from '@antv/l7-core'; } from '@antv/l7-core';
import { encodePickingColor, rgb2arr } from '@antv/l7-utils'; import {
decodePickingColor,
encodePickingColor,
rgb2arr,
} from '@antv/l7-utils';
import { injectable } from 'inversify'; import { injectable } from 'inversify';
const PickingStage = { const PickingStage = {
@ -67,12 +71,11 @@ export default class PixelPickingPlugin implements ILayerPlugin {
layer.hooks.afterPickingEncode.tap('PixelPickingPlugin', () => { layer.hooks.afterPickingEncode.tap('PixelPickingPlugin', () => {
const { enablePicking } = layer.getLayerConfig(); const { enablePicking } = layer.getLayerConfig();
// 区分选中高亮 和滑过高亮
if (enablePicking && layer.isVisible()) { if (enablePicking && layer.isVisible()) {
layer.models.forEach((model) => layer.models.forEach((model) =>
model.addUniforms({ model.addUniforms({
u_PickingStage: PickingStage.NONE, u_PickingStage: PickingStage.HIGHLIGHT,
u_PickingColor: [0, 0, 0],
u_HighlightColor: [0, 0, 0, 0],
}), }),
); );
} }
@ -86,6 +89,9 @@ export default class PixelPickingPlugin implements ILayerPlugin {
typeof highlightColor === 'string' typeof highlightColor === 'string'
? rgb2arr(highlightColor) ? rgb2arr(highlightColor)
: highlightColor || [1, 0, 0, 1]; : highlightColor || [1, 0, 0, 1];
layer.updateLayerConfig({
pickedFeatureID: decodePickingColor(new Uint8Array(pickedColor)),
});
layer.models.forEach((model) => layer.models.forEach((model) =>
model.addUniforms({ model.addUniforms({
u_PickingStage: PickingStage.HIGHLIGHT, u_PickingStage: PickingStage.HIGHLIGHT,

View File

@ -103,7 +103,6 @@ export default class ReglModel implements IModel {
...this.uniforms, ...this.uniforms,
...this.extractUniforms(options.uniforms || {}), ...this.extractUniforms(options.uniforms || {}),
}; };
const reglDrawProps: { const reglDrawProps: {
[key: string]: [key: string]:
| regl.Framebuffer | regl.Framebuffer

View File

@ -1,5 +1,5 @@
// @ts-ignore // @ts-ignore
import { PolygonLayer, Scale, Scene, PointLayer } from '@antv/l7'; import { PointLayer, PolygonLayer, Scale, Scene } from '@antv/l7';
import { Mapbox } from '@antv/l7-maps'; import { Mapbox } from '@antv/l7-maps';
import * as React from 'react'; import * as React from 'react';
@ -43,6 +43,7 @@ export default class ScaleComponent extends React.Component {
'#CF1D49', '#CF1D49',
]) ])
.shape('fill') .shape('fill')
.select(true)
.style({ .style({
opacity: 1.0, opacity: 1.0,
}); });
@ -57,14 +58,18 @@ export default class ScaleComponent extends React.Component {
type: 'quantile', type: 'quantile',
}) })
.size('point_count', [5, 10, 15, 20, 25]) .size('point_count', [5, 10, 15, 20, 25])
.animate(false) .animate(true)
.active(true) .select(true)
.color('yellow') .color('yellow')
.style({ .style({
opacity: 0.5, opacity: 0.5,
strokeWidth: 1, strokeWidth: 1,
}); });
scene.addLayer(pointLayer); scene.addLayer(pointLayer);
pointLayer.on('click', (e) => {
// console.log(e);
// pointLayer.setSelect(e.featureId);
});
const scaleControl = new Scale(); const scaleControl = new Scale();
scene.addControl(scaleControl); scene.addControl(scaleControl);

View File

@ -38,9 +38,12 @@ export default class ArcLineDemo extends React.Component {
}) })
.size(1) .size(1)
.shape('arc3d') .shape('arc3d')
.active(true) .select({
color: 'red',
})
.color('rgb(13,64,140)') .color('rgb(13,64,140)')
.animate({ .animate({
enable: true,
interval: 0.1, interval: 0.1,
duration: 2, duration: 2,
trailLength: 1.0, trailLength: 1.0,