feat: 优化风场图层的显示效果 (#1263)

* feat: 优化风场图层效果

* style: lint style
This commit is contained in:
YiQianYao 2022-07-29 17:16:46 +08:00 committed by GitHub
parent 9c9fa85cd3
commit 1a78586ee2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 65 deletions

View File

@ -36,9 +36,10 @@ export default class WindModel extends BaseModel {
// source: 'http://nomads.ncep.noaa.gov',
private frequency = new FrequencyController(7.2);
private cacheZoom: number;
public render() {
// TODO: 控制风场的平均更新频率
// Tip: 控制风场的平均更新频率
this.frequency.run(() => {
this.drawWind();
});
@ -71,12 +72,13 @@ export default class WindModel extends BaseModel {
height: 0,
width: 0,
});
this.cacheZoom = Math.floor(this.mapService.getZoom());
const glContext = this.rendererService.getGLContext();
this.imageCoords = source.data.dataArray[0].coordinates as [Point, Point];
this.imageCoords = source.data?.dataArray[0].coordinates as [Point, Point];
source.data.images.then((imageData: HTMLImageElement[]) => {
this.sizeScale = sizeScale;
source.data?.images?.then((imageData: HTMLImageElement[]) => {
this.sizeScale = sizeScale * this.getZoomScale();
const { imageWidth, imageHeight } = this.getWindSize();
@ -101,11 +103,11 @@ export default class WindModel extends BaseModel {
vMax,
image: imageData[0],
});
this.texture?.destroy();
this.texture = createTexture2D({
data: imageData[0],
width: imageData[0].width,
height: imageData[0].height,
width: imageWidth,
height: imageHeight,
});
this.layerService.updateLayerRenderList();
@ -120,7 +122,7 @@ export default class WindModel extends BaseModel {
primitive: gl.TRIANGLES,
depth: { enable: false },
blend: this.getBlend(),
// stencil: getMask(mask, maskInside),
stencil: getMask(mask, maskInside),
});
return [this.colorModel];
@ -130,8 +132,14 @@ export default class WindModel extends BaseModel {
const p1 = this.mapService.lngLatToPixel(this.imageCoords[0]);
const p2 = this.mapService.lngLatToPixel(this.imageCoords[1]);
const imageWidth = Math.floor((p2.x - p1.x) * this.sizeScale);
const imageHeight = Math.floor((p1.y - p2.y) * this.sizeScale);
const imageWidth = Math.min(
Math.floor((p2.x - p1.x) * this.sizeScale),
2048,
);
const imageHeight = Math.min(
Math.floor((p1.y - p2.y) * this.sizeScale),
2048,
);
return { imageWidth, imageHeight };
}
@ -182,6 +190,10 @@ export default class WindModel extends BaseModel {
});
}
private getZoomScale() {
return Math.min(((this.cacheZoom + 4) / 30) * 2, 2);
}
private drawWind() {
if (this.wind) {
const {
@ -197,15 +209,23 @@ export default class WindModel extends BaseModel {
rampColors = defaultRampColors,
sizeScale = 0.5,
} = this.layer.getLayerConfig() as IWindLayerStyleOptions;
if (typeof sizeScale === 'number' && sizeScale !== this.sizeScale) {
let newNumParticles = numParticles;
const currentZoom = Math.floor(this.mapService.getZoom());
if (
(typeof sizeScale === 'number' && sizeScale !== this.sizeScale) ||
currentZoom !== this.cacheZoom
) {
const zoomScale = this.getZoomScale();
this.sizeScale = sizeScale;
newNumParticles *= zoomScale;
const { imageWidth, imageHeight } = this.getWindSize();
this.wind.reSize(imageWidth, imageHeight);
this.cacheZoom = currentZoom;
}
this.wind.updateWindDir(uMin, uMax, vMin, vMax);
this.wind.updateParticelNum(numParticles);
this.wind.updateParticelNum(newNumParticles);
this.wind.updateColorRampTexture(rampColors);
@ -227,6 +247,13 @@ export default class WindModel extends BaseModel {
private drawColorMode() {
const { opacity } = this.layer.getLayerConfig() as IWindLayerStyleOptions;
this.layer.masks.map((m) => {
m.hooks.beforeRenderData.call();
m.hooks.beforeRender.call();
m.render();
m.hooks.afterRender.call();
});
this.colorModel.draw({
uniforms: {
u_opacity: opacity || 1.0,

View File

@ -368,7 +368,6 @@ export class Wind {
);
}
}
public draw() {
if (this.windData?.image) {
const gl = this.gl;
@ -393,11 +392,10 @@ export class Wind {
gl.viewport(0, 0, this.width, this.height);
gl.disable(gl.BLEND);
this.drawFullTexture(this.backgroundTexture, this.fadeOpacity);
this.drawParticles();
gl.disable(gl.BLEND);
this.pixels = new Uint8Array(4 * this.width * this.height);
gl.readPixels(
0,

View File

@ -19,64 +19,63 @@ export default class WindMap extends React.Component {
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [40, 30.3628],
center: [105, 35],
pitch: 0,
style: 'normal',
zoom: 2,
viewMode: '3D',
zoom: 4,
}),
});
this.scene = scene;
const pointLayer = new PointLayer({ zIndex: 1 })
.source(
[
{
lng: 121.107846,
lat: 30.267069,
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
.shape('circle')
.color('#f00')
.active(true)
.size(40)
.style({
stroke: '#fff',
storkeWidth: 2,
});
const styleOptions = {
uMin: -21.32,
uMax: 26.8,
vMin: -21.57,
vMax: 21.42,
numParticles: 65535 / 2,
fadeOpacity: 0.996,
rampColors: {
0.0: '#3288bd',
0.1: '#66c2a5',
0.2: '#abdda4',
0.3: '#e6f598',
0.4: '#fee08b',
0.5: '#fdae61',
0.6: '#f46d43', // f46d43
1.0: '#d53e4f',
},
sizeScale: 1,
};
// const pointLayer = new PointLayer({ zIndex: 1 })
// .source(
// [
// {
// lng: 121.107846,
// lat: 30.267069,
// },
// ],
// {
// parser: {
// type: 'json',
// x: 'lng',
// y: 'lat',
// },
// },
// )
// .shape('circle')
// .color('#f00')
// .active(true)
// .size(40)
// .style({
// stroke: '#fff',
// storkeWidth: 2,
// });
scene.on('loaded', () => {
scene.addLayer(pointLayer);
const styleOptions = {
uMin: -21.32,
uMax: 26.8,
vMin: -21.57,
vMax: 21.42,
numParticles: 65535,
fadeOpacity: 0.996,
rampColors: {
0.0: '#3288bd',
0.1: '#66c2a5',
0.2: '#abdda4',
0.3: '#e6f598',
0.4: '#fee08b',
0.5: '#fdae61',
0.6: '#f46d43', // f46d43
1.0: '#d53e4f',
},
sizeScale: 0.5,
};
// scene.addLayer(pointLayer);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json',
)
@ -85,6 +84,8 @@ export default class WindMap extends React.Component {
const layer = new WindLayer({
mask: true,
maskfence: maskData,
// maskColor: '#fff',
// maskOpacity: 0.5,
});
layer
.source(
@ -92,7 +93,8 @@ export default class WindMap extends React.Component {
{
parser: {
type: 'image',
extent: [-180, -85, 180, 85],
// extent: [-180, -85, 180, 85],
extent: [70, 16, 136, 54],
},
},
)