产汇流模拟是水文学、地理学和环境科学等领域中的一种重要研究方法,主要用于模拟降水转化为地表径流的过程。这个过程涉及到降雨量的分布、土壤类型、地形地貌、植被覆盖、土地利用等因素对水分渗透、储存和流失的影响。
具体来说,产汇流模拟主要包括以下几个步骤:
1. 数据准备:收集和处理所需的输入数据,包括DEM(数字高程模型)以获取地形信息,气象站观测的降雨数据,土壤类型及参数,植被覆盖度,土地利用类型等。
2. 流域划分与特征提取:根据DEM进行子流域划分,并计算各个子流域的相关水文特性,如面积、平均坡度、流向、蓄水能力等。
3. 选择或构建模型:选择适合特定流域特性的产汇流模型,例如基于物理过程的连续方程模型(如SAC-SMA、SWAT、HEC-HMS等),或者基于统计经验关系的模型(如Green-Ampt、Philip infiltration模型等)。
4. 模型参数率定与校验:使用历史观测数据对模型参数进行率定,通过对比模拟结果与实测径流数据,优化模型参数,提高模型预测精度。
5. 模拟运行与分析:输入未来气候变化情景下的降雨数据,运行模型进行产汇流模拟,进而分析不同情境下径流变化规律,为水资源管理、洪水预警、水利工程设计以及生态环境保护等方面提供决策支持。
6. 成果展示与应用:将模拟结果以图表、地图等形式直观展示,供决策者和科研人员参考和分析。在实际应用中,产汇流模拟能够帮助我们更好地理解并预测水资源的时空动态变化,为合理开发、管理和保护水资源提供科学依据。
产汇流模拟软件成果展示
应用场景
山洪模拟:
产汇流基础数据
产汇流模拟关键代码实现
entities:[], isRLayerPanel: true, url: '/static/localRain.json', dataPath: '', options:{ id:'chl', name:'产汇流模拟', isShow:false }, location: { "destination":{"x":-1289406.2535686514,"y":5146053.096414656,"z":3551139.094344541},"orientation":{"heading":6.240559515291201,"pitch":-1.4942952503663536,"roll":0.0021848124262540125}, duration: 2 }
//计算经纬度步进长度 _calcStep:function(){ let isextent = (this.extent.length!=0); let calcExtent = isextent?this.extent:this.initExtent; let calcSpeed = this.speedRate; this.calc_speedRate = [(calcExtent[1]-calcExtent[0])/calcSpeed,(calcExtent[3]-calcExtent[2])/calcSpeed]; }
animate: function () { let self = this, field = self.windField; let nextLng = null, nextLat = null, uv = null; self.particles.forEach(function (particle) { if (particle.age == null || particle.age <= 0) { self.randomParticle(particle); } if (particle.age > 0) { let x = particle.x, y = particle.y, tlng = particle.tlng, tlat = particle.tlat; let gridpos = self._togrid(tlng,tlat); let tx = gridpos[0]; let ty = gridpos[1]; if (!self.isInExtent(tlng,tlat)) { particle.age = 0; } else { uv = field.getIn(tx, ty); nextLng = tlng + self.calc_speedRate[0] * uv[0]; nextLat = tlat - self.calc_speedRate[1] * uv[1]; particle.lng = tlng; particle.lat = tlat; particle.x = tx; particle.y = ty; particle.tlng = nextLng; particle.tlat = nextLat; particle.age--; } } }); if (self.particles.length <= 0) this.removeLines(); self._drawLines(); }, //粒子是否在地图范围内 isInExtent:function(lng,lat){ let calcExtent = this.initExtent; if((lng>=calcExtent[0] && lng<=calcExtent[1]) && (lat>=calcExtent[2] && lat<=calcExtent[3])) return true; return false; }, _resize:function(width,height){ this.canvasWidth = width; this.canvasHeight = height; }
removeLines: function () { window.cancelAnimationFrame(this.animateFrame); this.isdistory = true; this.canvas.width = 1; document.getElementById('content').removeChild(this.canvas); }, //根据粒子当前所处的位置(棋盘网格位置),计算经纬度,在根据经纬度返回屏幕坐标 _tomap: function (lng,lat,particle) { let ct3 = Cartesian3.fromDegrees(lng,lat,0); // 判断当前点是否在地球可见端 let isVisible = new EllipsoidalOccluder(Ellipsoid.WGS84, this.viewer.camera.position).isPointVisible(ct3); let pos = SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, ct3); if(!isVisible){ particle.age = 0; } // console.log(pos); return pos?[pos.x,pos.y]:null; }, //根据经纬度,算出棋盘格位置 _togrid: function (lng,lat) { let field = this.windField; let x = (lng-this.initExtent[0])/(this.initExtent[1]-this.initExtent[0])*(field.cols-1); let y = (this.initExtent[3]-lat)/(this.initExtent[3]-this.initExtent[2])*(field.rows-1); return [x,y]; }, _drawLines: function () { let self = this; let particles = this.particles; this.canvasContext.lineWidth = self.lineWidth; //后绘制的图形和前绘制的图形如果发生遮挡的话,只显示后绘制的图形跟前一个绘制的图形重合的前绘制的图形部分,示例:https://www.w3school.com.cn/tiy/t.asp?f=html5_canvas_globalcompop_all this.canvasContext.globalCompositeOperation = "destination-in"; this.canvasContext.fillRect(0,0,this.canvasWidth,this.canvasHeight); this.canvasContext.globalCompositeOperation = "lighter";//重叠部分的颜色会被重新计算 this.canvasContext.globalAlpha = 0.9; this.canvasContext.beginPath(); this.canvasContext.strokeStyle = this.color; particles.forEach(function (particle) { let movetopos = self._tomap(particle.lng, particle.lat,particle); let linetopos = self._tomap(particle.tlng, particle.tlat,particle); // let movetopos = self._tomap(particle.tlng, particle.tlat,particle); // let linetopos = self._tomap(particle.lng, particle.lat,particle); // console.log(movetopos,linetopos); if(movetopos!=null && linetopos!=null){ self.canvasContext.moveTo(movetopos[0],movetopos[1]); self.canvasContext.lineTo(linetopos[0],linetopos[1]); // self.canvasContext.moveTo(linetopos[0],linetopos[1]); // self.canvasContext.lineTo(movetopos[0],movetopos[1]); } }); this.canvasContext.stroke(); }, //随机数生成器(小数) fRandomByfloat:function(under, over){ return under+Math.random()*(over-under); }, //随机数生成器(整数) fRandomBy:function(under, over){ switch(arguments.length){ case 1: return parseInt(Math.random()*under+1); case 2: return parseInt(Math.random()*(over-under+1) + under); default: return 0; } }, //根据当前产汇流场extent随机生成粒子 randomParticle: function (particle) { let safe = 30,x=-1, y=-1,lng=null,lat=null; let hasextent = this.extent.length!=0; let calc_extent = hasextent?this.extent:this.initExtent; try{ do { try{ if(hasextent){ let pos_x = this.fRandomBy(0,this.canvasWidth); let pos_y = this.fRandomBy(0,this.canvasHeight); let cartesian = this.viewer.camera.pickEllipsoid(new Cartesian2(pos_x, pos_y), this.viewer.scene.globe.ellipsoid); let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian); if(cartographic){ //将弧度转为度的十进制度表示 lng = CMath.toDegrees(cartographic.longitude); lat = CMath.toDegrees(cartographic.latitude); } }else{ lng = this.fRandomByfloat(calc_extent[0],calc_extent[1]); lat = this.fRandomByfloat(calc_extent[2],calc_extent[3]); } }catch(e){ } if(lng){ let gridpos = this._togrid(lng,lat); x = gridpos[0]; y = gridpos[1]; } } while (this.windField.getIn(x, y)[2] <= 0 && safe++ < 30); }catch (e) { } try{ let field = this.windField; let uv = field.getIn(x, y); particle.speed = uv[2]; particle.lng = lng; particle.lat = lat; particle.x = x; particle.y = y; let nextLng = lng + this.calc_speedRate[0] * uv[0]; let nextLat = lat + this.calc_speedRate[1] * uv[1]; particle.tlng = nextLng; particle.tlat = nextLat; particle.age = Math.round(Math.random() * this.maxAge);//每一次生成都不一样 } catch (e) { } return particle; }
最后分享下地图下载器下载地址
通过百度网盘分享的文件:V-2.0jbr…
链接:https://pan.baidu.com/s/1AiFKTTknkEHkJ7t4nQ2P1g
提取码:8664
复制这段内容打开「百度网盘APP 即可获取」
如果对您有所帮助,请点赞打赏支持!
技术合作交流qq:2401315930