diff --git a/packages/layers/src/wind/models/wind.ts b/packages/layers/src/wind/models/wind.ts index 83eeea8db1..dc0979f7d5 100644 --- a/packages/layers/src/wind/models/wind.ts +++ b/packages/layers/src/wind/models/wind.ts @@ -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, diff --git a/packages/layers/src/wind/models/windRender.ts b/packages/layers/src/wind/models/windRender.ts index 9565a3b264..7a3185679e 100644 --- a/packages/layers/src/wind/models/windRender.ts +++ b/packages/layers/src/wind/models/windRender.ts @@ -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, diff --git a/stories/Map/components/amap2demo_wind.tsx b/stories/Map/components/amap2demo_wind.tsx index 5015a52c0f..8f82860f55 100644 --- a/stories/Map/components/amap2demo_wind.tsx +++ b/stories/Map/components/amap2demo_wind.tsx @@ -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], }, }, )