首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java实现林火蔓延路径算法

Java实现林火蔓延路径算法

作者头像
盹猫
发布2025-07-22 18:16:16
发布2025-07-22 18:16:16
6600
代码可运行
举报
运行总次数:0
代码可运行

欢迎来到 盹猫(>^ω^<)的博客 本篇文章主要介绍了 [Java实现林火蔓延路径算法] ❤博主广交技术好友,喜欢文章的可以关注一下❤

一、写作目的

记录正在进行的森林防火项目中林火蔓延功能,本篇文章可以较好的实现森林防火蔓延,但还存在很多不足,如:很多参数只能使用默认值,所以蔓延范围仅供参考。(如果底层设备获取的数据充足,那当我没说)。

二、参数说明

参数名

解释

x1

经度

x2

纬度

sj

风向偏移量(代码中这个要>n才会调用蔓延算法)

n

n = 0:表示风向角度范围在 225 度左右。 n = 1:表示风向角度范围在 270 度左右。 n = 2:表示风向角度范围在 315 度左右。 n = 3:表示风向角度范围在 0 度左右。 n = 4:表示风向角度范围在 45 度左右。 n = 5:表示风向角度范围在 90 度左右。 n = 6:表示风向角度范围在 135 度左右。 n = 7:表示风向角度范围在 180 度左右

Winddir

风向

Time

时间

s

矿质阻尼系数(不太懂,默认设为0)

v

理想反应速度:快速燃烧(50) 中等燃烧(10) 缓慢燃烧(1)

speed

风速

Wn

静可燃物载量(就是有多少东西可供燃烧),估值或直接用下面的值 小型树木或灌木(500千克) 中型树木(5000千克) 大型树木(50万千克)

h

可燃物烩值 (木材:17)

q

修正系数 (默认1)

density

密度修正系数 (默认1)

a

修正系数 (默认1)

Qi

密度(默认1)

p

修正参数 (默认1)

slope

坡度

三、代码方法

1.计算风速修正系数
代码语言:javascript
代码运行次数:0
运行
复制
private double CalWindCorr(double speed, double p) {
    // 计算⻛速修正系数
    double Qw; //⻛速修正系数
    double B;
    double C;
    double E;
    double b; //燃料最佳紧密度
    double c; //最有可能的压缩⽐

    c = 1.2;
    E = 0.715 * (Math.pow(Math.E, (-0.01094 * p)));
    C = 7.47 * (Math.pow(Math.E, (-0.8711 * Math.pow(p, 0.55))));
    B = 0.15988 * Math.pow(p, 0.54);
    b = 0.20395 * Math.pow(p, -0.8189);

    Qw = C * Math.pow(3.284 * speed, B) * Math.pow(c / b, -E);

    return Qw;
}
2.计算坡度修正系数
代码语言:javascript
代码运行次数:0
运行
复制
public double CalSlopeCorr(double slope, double p) {
    // 计算坡度修正系数 p
    double Qs;
    Qs = 5.275 * Math.pow(p, -0.3) * (Math.tan(slope * Math.PI / 180)) * (Math.tan(slope * Math.PI / 180));
    return Qs;
}
3.计算火焰强度
代码语言:javascript
代码运行次数:0
运行
复制
private double CalIr(double v, double Wn, double h, double m, double s) {
    // 计算⽕焰强度
    // 理想反应速度 v
    // 可燃物烩值 h
    // 净可燃物载量 Wn
    // 湿度阻尼系数 m
    // 矿质阻尼系数 s
    double Ir;
    Ir = v * Wn * h * m * s;
    return Ir;
}
4.计算坐标
代码语言:javascript
代码运行次数:0
运行
复制
    public XY GetNextFeature(double x, double y, double s, int n,int sj,double fengxiang) {
        double s1;
        int m;
        XY c1 = new XY();
        int number = 80;
        switch (n) {
            case 0: { s1 = s * Math.sin((Math.PI) / 4); m = (int)(s1 / 80); if (fengxiang > 0 && fengxiang < 90) { c1.setX((x - m * 80 - 0.1 - number * sj)); c1.setY((y + m * 80 + 0.1 + number * sj)); }else if (fengxiang > 90 && fengxiang < 180) { c1.setX((x - m * 80 - 0.1 - number * sj-80*2));
                    c1.setY(y + m * 80 + 0.1 + number * sj+80*2); }else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x - m * 80 - 0.1 - number * sj - 80 * 3); c1.setY(y + m * 80 + 0.1 + number * sj + 80 * 3); }else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x - m * 80 - 0.1 - number * sj-80*1); c1.setY(y + m * 80 + 0.1 + number * sj+80*1); }else if (fengxiang == 0|| fengxiang == 360) { c1.setX(x - m * 80 - 0.1 - number * sj); c1.setY(y + m * 80 + 0.1 + number * sj); }else if (fengxiang == 90) { c1.setX(x - m * 80 - 0.1 - number * sj); c1.setY(y + m * 80 + 0.1 + number * sj); }else if (fengxiang == 180) { c1.setX(x - m * 80 - 0.1 - number * sj-80*1); c1.setY(y + m * 80 + 0.1 + number * sj+80*1); }else if (fengxiang == 270) { c1.setX(x - m * 80 - 0.1 - number * sj - 80*2); c1.setY(y + m * 80 + 0.1 + number * sj + 80*2); }break; }
            case 1: { s1 = s; m = (int)(s1 / 80); if (fengxiang > 0 && fengxiang < 90) { c1.setX(x - 0.1-80); c1.setY(y + m * 80 + number * sj + 0.1); }else if (fengxiang > 90 && fengxiang < 180) { c1.setX(x - 0.1 - 80); c1.setY(y + m * 80 + number * sj + 0.1+80*1); }else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x - 0.1 - 80); c1.setY(y + m * 80 + number * sj + 0.1+ 80 * 2); }else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x - 0.1 - 80); c1.setY(y + m * 80 + number * sj + 0.1 +80 * 2); }
                     else if (fengxiang == 0 || fengxiang == 360) { c1.setX(x - 0.1 - 80); c1.setY(y + m * 80 + number * sj + 0.1+80); }else if (fengxiang == 90) { c1.setX(x - 0.1 - 80); c1.setY(y + m * 80 + number * sj + 0.1); }else if (fengxiang == 180) { c1.setX(x - 0.1 - 80); c1.setY(y + m * 80 + number * sj + 0.1); }else if (fengxiang == 270) { c1.setX(x - 0.1 - 80); c1.setY(y + m * 80 + number * sj + 0.1+80*3); }break; }
            case 2: { s1 = s * Math.sin((Math.PI) / 4); m = (int)(s1 / 80); // c1.X = (x + m * 80 + number * sj + 0.1); // c1.Y = (y + m * 80 + number * sj + 0.1);
                    if (fengxiang > 0 && fengxiang < 90) { c1.setX((x + m * 80 + number * sj + 0.1)); c1.setY(y + m * 80 + number * sj + 0.1); }else if (fengxiang > 90 && fengxiang < 180) { c1.setX(x + m * 80 + number * sj + 0.1-80*2); c1.setY(y + m * 80 + number * sj + 0.1-80*2); }else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x + m * 80 + number * sj + 0.1 - 80 * 1); c1.setY(y + m * 80 + number * sj + 0.1 - 80 * 1); }else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x + m * 80 + number * sj + 0.1+80*5); c1.setY(y + m * 80 + number * sj + 0.1+80*5); }else if (fengxiang == 0 || fengxiang == 360) { c1.setX(x + m * 80 + number * sj + 0.1 + 80*3); c1.setY(y + m * 80 + number * sj + 0.1 + 80*3); }else if (fengxiang == 90) { c1.setX(x + m * 80 + number * sj + 0.1 + 80); c1.setY(y + m * 80 + number * sj + 0.1 + 80); }
                    else if (fengxiang == 180) { c1.setX(x + m * 80 + number * sj + 0.1); c1.setY(y + m * 80 + number * sj + 0.1); }else if (fengxiang == 270) { c1.setX(x + m * 80 + number * sj + 0.1 + 80*2); c1.setY(y + m * 80 + number * sj + 0.1 + 80*2); }break; }
            case 3: { s1 = s; m = (int)(s1 / 80); if (fengxiang > 0 && fengxiang < 90) { c1.setX(x + m * 80 + 0.1 + number * sj + 80 * 2); c1.setY(y + 0.1 +80); }else if (fengxiang > 90 && fengxiang < 180) { c1.setX(x + m * 80 + 0.1 + number * sj); c1.setY(y + 0.1 + 80); }else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x + m * 80 + 0.1 + number * sj); c1.setY(y + 0.1 + 80); }else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x + m * 80 + 0.1 + number * sj+80 * 2); c1.setY(y + 0.1 + 80); }else if (fengxiang == 0 || fengxiang == 360) { c1.setX(x + m * 80 + 0.1 + number * sj + 80 * 3); c1.setY(y + 0.1 + 80); }else if (fengxiang == 90) { c1.setX(x + m * 80 + 0.1 + number * sj + 80 * 1); c1.setY(y + 0.1 + 80); }else if (fengxiang == 180) { c1.setX(x + m * 80 + 0.1 + number * sj); c1.setY(y + 0.1 + 80); }else if (fengxiang == 270) { c1.setX(x + m * 80 + 0.1 + number * sj + 80 *1); c1.setY(y + 0.1 + 80); }break; }
            case 4: { s1 = s * Math.sin((Math.PI) / 4); m = (int)((s1 / 80)); if (fengxiang > 0 && fengxiang < 90) { c1.setX(x + m * 80 + number * sj + 80 * 3); c1.setY(y - m * 80 - number * sj - 80 * 3); }else if (fengxiang > 90 && fengxiang < 180) { c1.setX(x + m * 80 + number * sj + 0.1); c1.setY(y - m * 80 - number * sj - 0.1); }else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x + m * 80 + number * sj + 0.1); c1.setY(y - m * 80 - number * sj - 0.1); }else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x + m * 80 + number * sj + 0.1); c1.setY(y - m * 80 - number * sj - 0.1); }else if (fengxiang == 0 || fengxiang == 360) { c1.setX(x + m * 80 + number * sj + 80 * 2); c1.setY(y - m * 80 - number * sj - 80 * 2); }else if (fengxiang == 90) { c1.setX(x + m * 80 + number * sj + 80 * 2); c1.setY(y - m * 80 - number * sj - 80 * 2); }else if (fengxiang == 180) { c1.setX(x + m * 80 + number * sj + 0.1); c1.setY(y - m * 80 - number * sj - 0.1); }else if (fengxiang == 270) { c1.setX(x + m * 80 + number * sj + 0.1); c1.setY(y - m * 80 - number * sj - 0.1); }break; }
            case 5: { s1 = s; m = (int)(s1 / 80); if (fengxiang > 0 && fengxiang < 90) { c1.setX(x + 0.1 + 80); c1.setY(y - m * 80 - number * sj - 0.1- 80 * 2); }else if (fengxiang > 90 && fengxiang < 180) { c1.setX(x + 0.1 + 80);
                      c1.setY(y - m * 80 - number * sj - 0.1 - 80 * 1); }else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x + 0.1 + 80); c1.setY(y - m * 80 - number * sj - 0.1); ; }else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x + 0.1 + 80); c1.setY(y - m * 80 - number * sj - 0.1); }else if (fengxiang == 0 || fengxiang == 360) { c1.setX(x + 0.1 + 80); c1.setY(y - m * 80 - number * sj - 0.1 - 80 * 1); }else if (fengxiang == 90) { c1.setX(x + 0.1 + 80); c1.setY(y - m * 80 - number * sj - 0.1 - 80 * 3); }else if (fengxiang == 180) { c1.setX(x + 0.1 + 80); c1.setY(y - m * 80 - number * sj - 0.1 - 80 * 1); }else if (fengxiang == 270) { c1.setX(x + 0.1 + 80); c1.setY(y - m * 80 - number * sj - 0.1); }break; }
            case 6: { s1 = s * Math.sin((Math.PI) / 4); m = (int)((s1 / 80)); // c1.X = (x - m * 80 - 0.1 - number * sj); //c1.Y = (y - m * 80 - 0.1 - number * sj);
                      if (fengxiang > 0 && fengxiang < 90) { c1.setX(x - m * 80 - 0.1 - number * sj); c1.setY(y - m * 80 - 0.1 - number * sj); }else if (fengxiang > 90 && fengxiang < 180) { c1.setX(x - m * 80 - 0.1 - number * sj - 80 * 3); c1.setY(y - m * 80 - 0.1 - number * sj - 80 * 3); }else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x - m * 80 - 0.1 - number * sj- 80 * 1); c1.setY(y - m * 80 - 0.1 - number * sj-80 * 1); }else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x - m * 80 - 0.1 - number * sj);
                          c1.setY(y - m * 80 - 0.1 - number * sj); }else if (fengxiang == 0 || fengxiang == 360) { c1.setX(x - m * 80 - 0.1 - number * sj); c1.setY(y - m * 80 - 0.1 - number * sj); }else if (fengxiang == 90) { c1.setX(x - m * 80 - 0.1 - number * sj - 80 * 2); c1.setY(y - m * 80 - 0.1 - number * sj - 80 * 2); }else if (fengxiang == 180) { c1.setX(x - m * 80 - 0.1 - number * sj - 80 * 1); c1.setY(y - m * 80 - 0.1 - number * sj - 80 * 1); }else if (fengxiang == 270) { c1.setX(x - m * 80 - 0.1 - number * sj); c1.setY(y - m * 80 - 0.1 - number * sj); }break; }
            case 7: { s1 = s; m = (int)(s1 / 80);
                     if (fengxiang > 0 && fengxiang < 90) { c1.setX(x - m * 80 - number * sj); c1.setY(y - 0.1-80); }
                     else if (fengxiang > 90 && fengxiang < 180) { c1.setX(x - m * 80 - number * sj- 80 * 3);c1.setY(y - 0.1 - 80); }
                     else if (fengxiang > 180 && fengxiang < 270) { c1.setX(x - m * 80 - number * sj - 80 * 2); c1.setY(y - 0.1 - 80); }
                     else if (fengxiang > 270 && fengxiang < 360) { c1.setX(x - m * 80 - number * sj); c1.setY(y - 0.1 - 80); }
                     else if (fengxiang == 0 || fengxiang == 360) { c1.setX(x - m * 80 - number * sj); c1.setY(y - 0.1 - 80); }
                     else if (fengxiang == 90) { c1.setX(x - m * 80 - number * sj - 80 * 1); c1.setY(y - 0.1 - 80);}
                     else if (fengxiang == 180) { c1.setX(x - m * 80 - number * sj - 80 * 3); c1.setY(y - 0.1 - 80); }
                     else if (fengxiang == 270) { c1.setX(x - m * 80 - number * sj- 80 * 1); c1.setY(y - 0.1 - 80); }
                     break;
            }
        }
        return c1;
    }
5.计算蔓延速度
代码语言:javascript
代码运行次数:0
运行
复制
    public double SpreadSpeed(double n, double Winddir,double v,double Wn,double h,double m,double q,double density,double a,double Qi,double p,double slope,double speed ,double s) {
            double angle = 0;
            double Ir;
            double R;
            double K=1;
            if (n == 0) {
            angle = Math.abs(Winddir - 225);
            return K * (16 + 16 * (Math.cos(angle * Math.PI / 180))); }
        if (n == 1) { angle = Math.abs(Winddir - 270);
            return K * (15 + 15 * (Math.cos(angle * Math.PI / 180))); }
        if (n == 2) { angle = Math.abs(Winddir - 315) + 180; }if (n == 3) { angle = Math.abs(Winddir); }
        if (n == 4) { angle = Math.abs(Winddir - 45); }
        if (n == 5) { angle = Math.abs(Winddir - 90); }
        if (n == 6) { angle = Math.abs(Winddir - 135); return K * (12 + 12 * (Math.abs(angle * Math.PI / 180))); }
        if (n == 7) { angle = Math.abs(Winddir - 180); return K * (13 + 13 * (Math.cos(angle * Math.PI / 180))); }
        double speed_dy = CalWindCorr(speed,p);
        //⻛速修正系数
        double slop_dy = CalSlopeCorr(slope,p);
        Ir=CalIr(v,Wn,h,m,s);
        R = (Ir * q * (1 + speed_dy + slop_dy)) / (density * a * Qi);
        return K * (R + R * Math.cos(angle * Math.PI / 180));
    }
6.经纬度转换
代码语言:javascript
代码运行次数:0
运行
复制
    public XY lonLat2Mercator(double lon,double lat) { XY c1 = new XY(); c1.setX(lon * 20037508.34 / 180); double Y2 = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180); c1.setY(Y2 * 20037508.34 / 180); return c1; }
    public XY Mercator2lonLat(double x, double y) { XY c1 = new XY(); c1.setX(x / 20037508.34 * 180); double Y2 = y / 20037508.34 * 180; c1.setY(180 / Math.PI * (2 * Math.atan(Math.exp(Y2 * Math.PI / 180)) - Math.PI / 2)); return c1; }
7.主方法调用
代码语言:javascript
代码运行次数:0
运行
复制
    public XY HuygenSpread(double x1, double y1, int sj, int n, double Winddir, double Time, double s, double v, double speed, double Wn, double h, double q, double density, double a, double Qi, double p, double slope) {
        if (n< sj) {
            double huoyanspeed = SpreadSpeed(n,Winddir,v,Wn,h,n,q,density,a,Qi,p,slope,speed,s);
            System.err.println("huoyanspeed:"+huoyanspeed);
            double vtime = huoyanspeed * Time;
            System.err.println("vtime:"+vtime);
            XY c2 ; c2 = lonLat2Mercator(x1, y1);
            XY c1 = GetNextFeature(c2.getX(), c2.getY(), 1.4 * vtime, n,sj,Winddir);
            c1 = Mercator2lonLat(c1.getX(), c1.getY());
            return c1; }
                 else { XY c3 = new XY(); c3.setX(x1); c3.setY(y1);
            return c3; }
    }

注:因林火蔓延涉及因素太多,如静可燃物载量、矿质阻尼系数等存在估值,所以得出的结果仅供参考。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、写作目的
  • 二、参数说明
  • 三、代码方法
    • 1.计算风速修正系数
    • 2.计算坡度修正系数
    • 3.计算火焰强度
    • 4.计算坐标
    • 5.计算蔓延速度
    • 6.经纬度转换
    • 7.主方法调用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档