java+iClientOpenlayers实现城市内涝积涝模拟内涝模拟演进

news2024/11/15 14:05:44

程序实现效果图

洪水演进过程

 

 

一、应用背景 

城市内涝和积涝是一个严重的问题,特别是在气候变化的背景下。为了更好地了解这个问题,模拟城市内涝和积涝是非常重要的。这个过程可以帮助我们预测哪些区域可能会受到影响,以及在发生内涝和积涝时应该如何应对。同时,这个过程也可以帮助我们更好地规划城市建设,以减少内涝和积涝的发生。总的来说,城市内涝和积涝模拟是一个非常有价值的工具,可以帮助我们更好地应对这个问题,使城市更加安全和可持续。

城市内涝和积涝是一个全球性的问题,对城市的可持续发展和居民的生活质量都会产生影响。为了减少这些影响,我们需要采取措施来预测和应对内涝和积涝的发生。城市内涝和积涝模拟可以帮助我们更好地了解这个问题,以便我们在城市规划和应急响应方面做出更加科学和有效的决策。希望未来能够有更多的研究和投入来加强城市内涝和积涝模拟技术,让城市更加安全、可持续和宜居。

此外,还需要加强城市基础设施的建设,例如改善排水系统和城市绿地的规划。同时,也需要进行公众教育,提高居民的环保意识和应对内涝和积涝的能力。只有通过多方面的合作和努力,才能实现城市内涝和积涝的有效管理和缓解。让我们一起为创造更加美好的城市生活而努力。

除了进行城市内涝积涝模拟,我们还需要加强城市基础设施的建设。这包括改善排水系统和城市绿地的规划,以应对极端天气事件。与此同时,公众教育也很重要,我们需要提高居民的环保意识和应对内涝和积涝的能力。只有多方合作和努力,才能实现城市内涝和积涝的有效管理和缓解,让我们共同努力,创造更美好的城市生活。

二、常见城市内涝积涝场景

三、准备网格化的asc地形数据为模型计算提供基础数据(点位百万以上,如果卡顿,可分布式实现负载均衡解决)

四、关键java代码编写

/*
 * Copyright 2021 zdh,
 * zdh@gmail.com
 */
package wcontour;

import wcontour.KDTree.Euclidean;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

import static jdk.nashorn.internal.objects.Global.Infinity;

/**
 * Interpolate class - including the functions of interpolation
 *
 * @author zdh
 * @version $Revision: 1.6 $
 */
public class Interpolate {

    // <editor-fold desc="IDW">
    /**
     * Create grid x/y coordinate arrays with x/y delt
     *
     * @param Xlb x of left-bottom
     * @param Ylb y of left-bottom
     * @param Xrt x of right-top
     * @param Yrt y of right-top
     * @param XDelt x delt
     * @param YDelt y delt
     * @return X/Y coordinate arrays
     */
    public static List<double[]> createGridXY_Delt(double Xlb, double Ylb, double Xrt, double Yrt, double XDelt, double YDelt) {
        int i, Xnum, Ynum;
        Xnum = (int) ((Xrt - Xlb) / XDelt + 1);
        Ynum = (int) ((Yrt - Ylb) / YDelt + 1);
        double[] X = new double[Xnum];
        double[] Y = new double[Ynum];
        for (i = 0; i < Xnum; i++) {
            X[i] = Xlb + i * XDelt;
        }
        for (i = 0; i < Ynum; i++) {
            Y[i] = Ylb + i * YDelt;
        }

        List<double[]> values = new ArrayList<>();
        values.add(X);
        values.add(Y);
        return values;
    }

    /**
     * Create grid X/Y coordinate
     *
     * @param Xlb X left bottom 左下 x
     * @param Ylb Y left bottom
     * @param Xrt X right top   右上 x
     * @param Yrt Y right top
     * @param X X coordinate x 坐标
     * @param Y Y coordinate y 坐标
     *
     *  根据x,y 的边界值,在边界值范围内生成一组 x[] 和 一组 y[]
     */
    public static void createGridXY_Num(double Xlb, double Ylb, double Xrt, double Yrt,
            double[] X, double[] Y) {
        System.out.println("Interpolate.createGridXY_Num");
        int i;
        double XDelt, YDelt;
        int Xnum = X.length;
        int Ynum = Y.length;
        XDelt = (Xrt - Xlb) / Xnum;
        YDelt = (Yrt - Ylb) / Ynum;
        for (i = 0; i < Xnum; i++) {
            X[i] = Xlb + i * XDelt;
        }
        for (i = 0; i < Ynum; i++) {
            Y[i] = Ylb + i * YDelt;
        }
    }

    /**
     * 用IDW邻接法插值
     * Interpolation with IDW neighbor method
     *
     * @param SCoords discrete data array
     * @param X grid X array
     * @param Y grid Y array
     * @param NumberOfNearestNeighbors number of nearest neighbors
     * @return grid data
     */
    public static double[][] interpolation_IDW_Neighbor(double[][] SCoords, double[] X, double[] Y,
            int NumberOfNearestNeighbors) {
        int rowNum, colNum, pNum;
        colNum = X.length;
        rowNum = Y.length;
        pNum = SCoords.length;
        double[][] GCoords = new double[rowNum][colNum];
        int i, j, p, l, aP;
        double w, SV, SW, aMin;
        int points;
        points = NumberOfNearestNeighbors;
        Object[][] NW = new Object[2][points];

        //---- Do interpolation
        for (i = 0; i < rowNum; i++) {
            for (j = 0; j < colNum; j++) {
                GCoords[i][j] = -999.0;
                SV = 0;
                SW = 0;
                for (p = 0; p < points; p++) {
                    if (X[j] == SCoords[p][0] && Y[i] == SCoords[p][1]) {
                        GCoords[i][j] = SCoords[p][2];
                        break;
                    } else {
                        w = 1 / (Math.pow(X[j] - SCoords[p][0], 2) + Math.pow(Y[i] - SCoords[p][1], 2));
                        NW[0][p] = w;
                        NW[1][p] = p;
                    }
                }
                if (GCoords[i][j] == -999.0) {
                    for (p = points; p < pNum; p++) {
                        if (Math.pow(X[j] - SCoords[p][0], 2) + Math.pow(Y[i] - SCoords[p][1], 2) == 0) {
                            GCoords[i][j] = SCoords[p][2];
                            break;
                        } else {
                            w = 1 / (Math.pow(X[j] - SCoords[p][0], 2) + Math.pow(Y[i] - SCoords[p][1], 2));
                            aMin = Double.parseDouble(NW[0][0].toString());
                            aP = 0;
                            for (l = 1; l < points; l++) {
                                if (Double.parseDouble(NW[0][l].toString()) < aMin) {
                                    aMin = Double.parseDouble(NW[0][l].toString());
                                    aP = l;
                                }
                            }
                            if (w > aMin) {
                                NW[0][aP] = w;
                                NW[1][aP] = p;
                            }
                        }
                    }
                    if (GCoords[i][j] == -999.0) {
                        for (p = 0; p < points; p++) {
                            SV += Double.parseDouble(NW[0][p].toString()) * SCoords[Integer.parseInt(NW[1][p].toString())][2];
                            SW += Double.parseDouble(NW[0][p].toString());
                        }
                        GCoords[i][j] = SV / SW;
                    }
                }
            }
        }

        //---- Smooth with 5 points
        double s = 0.5;
        for (i = 1; i < rowNum - 1; i++) {
            for (j = 1; j < colNum - 1; j++) {
                GCoords[i][j] = GCoords[i][j] + s / 4 * (GCoords[i + 1][j] + GCoords[i - 1][j]
                        + GCoords[i][j + 1] + GCoords[i][j - 1] - 4 * GCoords[i][j]);
            }
        }

        return GCoords;
    }

    /**
     * 用IDW邻接法插值
     * Interpolation with IDW neighbor method
     *
     * @param SCoords discrete data array
     * @param X grid X array
     * @param Y grid Y array
     * @param NumberOfNearestNeighbors number of nearest neighbors
     * @param unDefData undefine data
     * @return interpolated grid data
     */
    public static double[][] interpolation_IDW_Neighbor(double[][] SCoords, double[] X, double[] Y,
            int NumberOfNearestNeighbors, double unDefData) {
        int rowNum, colNum, pNum;
        colNum = X.length;
        rowNum = Y.length;
        pNum = SCoords.length;
        double[][] GCoords = new double[rowNum][colNum];
        int i, j, p, l, aP;
        double w, SV, SW, aMin;
        int points;
        points = NumberOfNearestNeighbors;
        double[] AllWeights = new double[pNum];
        double[][] NW = new double[2][points];
        int NWIdx;

        //---- Do interpolation with IDW method
        for (i = 0; i < rowNum; i++) {
            for (j = 0; j < colNum; j++) {
                GCoords[i][j] = unDefData;
                SV = 0;
                SW = 0;
                NWIdx = 0;
                for (p = 0; p < pNum; p++) {
                    if (SCoords[p][2] == unDefData) {
                        AllWeights[p] = -1;
                        continue;
                    }
                    if (X[j] == SCoords[p][0] && Y[i] == SCoords[p][1]) {
                        GCoords[i][j] = SCoords[p][2];
                        break;
                    } else {
                        w = 1 / (Math.pow(X[j] - SCoords[p][0], 2) + Math.pow(Y[i] - SCoords[p][1], 2));
                        AllWeights[p] = w;
                        if (NWIdx < points) {
                            NW[0][NWIdx] = w;
                            NW[1][NWIdx] = p;
                        }
                        NWIdx += 1;
                    }
                }

                if (GCoords[i][j] == unDefData) {
                    for (p = 0; p < pNum; p++) {
                        w = AllWeights[p];
                        if (w == -1) {
                            continue;
                        }

                        aMin = NW[0][0];
                        aP = 0;
                        for (l = 1; l < points; l++) {
                            if ((double) NW[0][l] < aMin) {
                                aMin = (double) NW[0][l];
                                aP = l;
                            }
                        }
                        if (w > aMin) {
                            NW[0][aP] = w;
                            NW[1][aP] = p;
                        }
                    }
                    for (p = 0; p < points; p++) {
                        SV += (double) NW[0][p] * SCoords[(int) NW[1][p]][2];
                        SW += (double) NW[0][p];
                    }
                    GCoords[i][j] = SV / SW;
                }
            }
        }

        //---- Smooth with 5 points
        double s = 0.5;
        for (i = 1; i < rowNum - 1; i++) {
            for (j = 1; j < colNum - 1; j++) {
                GCoords[i][j] = GCoords[i][j] + s / 4 * (GCoords[i + 1][j] + GCoords[i - 1][j] + GCoords[i][j + 1]
                        + GCoords[i][j - 1] - 4 * GCoords[i][j]);
            }

        }

        return GCoords;
    }

    /**
     * IDW半径法插值
     *
     * 反距离权重法
     * Interpolation with IDW radius method
     *
     * @param SCoords discrete data array
     * @param X grid X array
     * @param Y grid Y array
     * @param NeededPointNum needed at least point number
     * @param radius search radius
     * @param unDefData undefine data
     * @return interpolated grid data 插值后的网格数据
     */
    public static double[][] interpolation_IDW_Radius(double[][] SCoords, double[] X, double[] Y,
            int NeededPointNum, double radius, double unDefData) {
        System.out.println("Interpolate.interpolation_IDW_Radius");
        int rowNum, colNum, pNum;
        colNum = X.length;
        rowNum = Y.length;
        pNum = SCoords.length;
        double[][] GCoords = new double[rowNum][colNum];
        int i, j, p, vNum;
        double w, SV, SW;
        boolean ifPointGrid;

        //---- Do interpolation
        for (i = 0; i < rowNum; i++) {
            for (j = 0; j < colNum; j++) {
                GCoords[i][j] = unDefData;
                ifPointGrid = false;
                SV = 0;
                SW = 0;
                vNum = 0;
                for (p = 0; p < pNum; p++) {
                    if (SCoords[p][2] == unDefData) {
                        continue;
                    }

                    if (SCoords[p][0] < X[j] - radius || SCoords[p][0] > X[j] + radius || SCoords[p][1] < Y[i] - radius
                            || SCoords[p][1] > Y[i] + radius) {
                        continue;
                    }

                    if (X[j] == SCoords[p][0] && Y[i] == SCoords[p][1]) {
                        GCoords[i][j] = SCoords[p][2];
                        ifPointGrid = true;
                        break;
                    } else if (Math.sqrt(Math.pow(X[j] - SCoords[p][0], 2)
                            + Math.pow(Y[i] - SCoords[p][1], 2)) <= radius) {
                        w = 1 / (Math.pow(X[j] - SCoords[p][0], 2) + Math.pow(Y[i] - SCoords[p][1], 2));
                        SW = SW + w;
                        SV = SV + SCoords[p][2] * w;
                        vNum += 1;
                    }
                }

                if (!ifPointGrid) {
                    if (vNum >= NeededPointNum) {
                        GCoords[i][j] = SV / SW;
                    }
                }
            }
        }

        //---- Smooth with 5 points
        double s = 0.5;
        for (i = 1; i < rowNum - 1; i++) {
            for (j = 1; j < colNum - 2; j++) {
                if (GCoords[i][j] == unDefData || GCoords[i + 1][j] == unDefData || GCoords[i - 1][j]
                        == unDefData || GCoords[i][j + 1] == unDefData || GCoords[i][j - 1] == unDefData) {
                    continue;
                }
                GCoords[i][j] = GCoords[i][j] + s / 4 * (GCoords[i + 1][j] + GCoords[i - 1][j] + GCoords[i][j + 1]
                        + GCoords[i][j - 1] - 4 * GCoords[i][j]);
            }
        }

        return GCoords;
    }

    /**
     * Interpolation with IDW radius method - using KDTree for fast search
     *
     * @param stData discrete data array
     * @param xGrid grid X array
     * @param yGrid grid Y array
     * @param neededPointNum needed at least point number
     * @param radius search radius
     * @param fillValue Fill value
     * @return interpolated grid data
     */
    public static double[][] idw_Radius_kdTree(double[][] stData, double[] xGrid, double[] yGrid,
            int neededPointNum, double radius, double fillValue) {
        Euclidean<double[]> kdtree = new Euclidean<>(2);
        int l = stData.length;

        for (int i = 0; i < l; i++) {
            //Avoid key repeat
            double nodex = stData[i][0] + (Math.random() * 10e-5);
            double nodey = stData[i][1] + (Math.random() * 10e-5);
            kdtree.addPoint(new double[]{nodex, nodey}, new double[]{stData[i][0], stData[i][1], stData[i][2]});
        }

        int w = xGrid.length;
        int h = yGrid.length;

        double[][] grid = new double[h][w];
        for (int i = 0; i < h; i++) {
            double yValue = yGrid[i];
            for (int j = 0; j < w; j++) {
                double xValue = xGrid[j];
                List<double[]> nearPntList = kdtree.ballSearch(new double[]{xValue, yValue}, radius);
                int nearSize = nearPntList.size();
                if (nearSize < neededPointNum) {
                    grid[i][j] = fillValue;
                    continue;
                }

                double z_sum = 0.0;
                double weight_sum = 0.0;
                for (int k = 0; k < nearSize; k++) {
                    double[] xyz = nearPntList.get(k);
                    double distance = Point2D.Double.distance(xValue, yValue, xyz[0], xyz[1]);
                    if (distance <= radius && distance > 0) {
                        weight_sum += radius / distance;
                        z_sum += radius / distance * xyz[2];
                    } else if (Math.abs(distance) < 0.0001) {  //Using point value when the grid is point
                        z_sum = xyz[2];
                        weight_sum = 1.0f;
                        break;
                    }
                }
                if (Math.abs(weight_sum) < 0.0001) {
                    grid[i][j] = fillValue;
                } else {
                    grid[i][j] = z_sum / weight_sum;
                }
            }
        }
        return grid;
    }

    /**
     * Interpolate from grid data
     *
     * @param GridData input grid data
     * @param X input x coordinates
     * @param Y input y coordinates
     * @param unDefData undefine data
     * @param nX output x coordinate
     * @param nY output y coordinate
     * @return output grid data
     */
    public static double[][] interpolation_Grid(double[][] GridData, double[] X, double[] Y, double unDefData,
            double[] nX, double[] nY) {
        int nxNum = X.length * 2 - 1;
        int nyNum = Y.length * 2 - 1;
        nX = new double[nxNum];
        nY = new double[nyNum];
        double[][] nGridData = new double[nyNum][nxNum];
        int i, j;
        double a, b, c, d;
        List<Double> dList;
        for (i = 0; i < nxNum; i++) {
            if (i % 2 == 0) {
                nX[i] = X[i / 2];
            } else {
                nX[i] = (X[(i - 1) / 2] + X[(i - 1) / 2 + 1]) / 2;
            }
        }
        for (i = 0; i < nyNum; i++) {
            if (i % 2 == 0) {
                nY[i] = Y[i / 2];
            } else {
                nY[i] = (Y[(i - 1) / 2] + Y[(i - 1) / 2 + 1]) / 2;
            }
            for (j = 0; j < nxNum; j++) {
                if (i % 2 == 0 && j % 2 == 0) {
                    nGridData[i][j] = GridData[i / 2][j / 2];
                } else if (i % 2 == 0 && j % 2 != 0) {
                    a = GridData[i / 2][(j - 1) / 2];
                    b = GridData[i / 2][(j - 1) / 2 + 1];
                    dList = new ArrayList<>();
                    if (a != unDefData) {
                        dList.add(a);
                    }
                    if (b != unDefData) {
                        dList.add(b);
                    }

                    if (dList.isEmpty()) {
                        nGridData[i][j] = unDefData;
                    } else if (dList.size() == 1) {
                        nGridData[i][j] = dList.get(0);
                    } else {
                        nGridData[i][j] = (a + b) / 2;
                    }
                } else if (i % 2 != 0 && j % 2 == 0) {
                    a = GridData[(i - 1) / 2][j / 2];
                    b = GridData[(i - 1) / 2 + 1][j / 2];
                    dList = new ArrayList<>();
                    if (a != unDefData) {
                        dList.add(a);
                    }
                    if (b != unDefData) {
                        dList.add(b);
                    }

                    if (dList.isEmpty()) {
                        nGridData[i][j] = unDefData;
                    } else if (dList.size() == 1) {
                        nGridData[i][j] = dList.get(0);
                    } else {
                        nGridData[i][j] = (a + b) / 2;
                    }
                } else {
                    a = GridData[(i - 1) / 2][(j - 1) / 2];
                    b = GridData[(i - 1) / 2][(j - 1) / 2 + 1];
                    c = GridData[(i - 1) / 2 + 1][(j - 1) / 2 + 1];
                    d = GridData[(i - 1) / 2 + 1][(j - 1) / 2];
                    dList = new ArrayList<>();
                    if (a != unDefData) {
                        dList.add(a);
                    }
                    if (b != unDefData) {
                        dList.add(b);
                    }
                    if (c != unDefData) {
                        dList.add(c);
                    }
                    if (d != unDefData) {
                        dList.add(d);
                    }

                    if (dList.isEmpty()) {
                        nGridData[i][j] = unDefData;
                    } else if (dList.size() == 1) {
                        nGridData[i][j] = dList.get(0);
                    } else {
                        double aSum = 0;
                        for (double dd : dList) {
                            aSum += dd;
                        }
                        nGridData[i][j] = aSum / dList.size();
                    }
                }
            }
        }

        return nGridData;
    }

    // </editor-fold>
    // <editor-fold desc="Cressman">
    /**
     * Cressman analysis
     *
     * @param stationData station data array - x,y,value
     * @param X x array
     * @param Y y array
     * @param unDefData undefine data
     * @return grid data
     */
    public static double[][] cressman(double[][] stationData, double[] X, double[] Y, double unDefData) {
        List<Double> radList = new ArrayList<>();
        radList.add(10.0);
        radList.add(7.0);
        radList.add(4.0);
        radList.add(2.0);
        radList.add(1.0);

        return cressman(stationData, X, Y, unDefData, radList);
    }

    /**
     * Cressman analysis
     *
     * @param stData station data array - x,y,value
     * @param X x array
     * @param Y y array
     * @param unDefData undefine data
     * @param radList radii list
     * @return result grid data
     */
    public static double[][] cressman(double[][] stData, double[] X, double[] Y, double unDefData, List<Double> radList) {
        int xNum = X.length;
        int yNum = Y.length;
        int pNum = stData.length;
        double[][] gridData = new double[yNum][xNum];
        int irad = radList.size();
        int i, j;

        //Loop through each stn report and convert stn lat/lon to grid coordinates
        double xMin = X[0];
        double xMax = X[X.length - 1];
        double yMin = Y[0];
        double yMax = Y[Y.length - 1];
        double xDelt = X[1] - X[0];
        double yDelt = Y[1] - Y[0];
        double x, y;
        double sum = 0, total = 0;
        int stNum = 0;
        double[][] stationData = new double[pNum][3];
        for (i = 0; i < pNum; i++) {
            x = stData[i][0];
            y = stData[i][1];
            stationData[i][0] = (x - xMin) / xDelt;
            stationData[i][1] = (y - yMin) / yDelt;
            stationData[i][2] = stData[i][2];
            if (stationData[i][2] != unDefData) {
                total += stationData[i][2];
                stNum += 1;
            }
        }
        total = total / stNum;

        //Initial the arrays
        double HITOP = -999900000000000000000.0;
        double HIBOT = 999900000000000000000.0;
        double[][] TOP = new double[yNum][xNum];
        double[][] BOT = new double[yNum][xNum];
        for (i = 0; i < yNum; i++) {
            for (j = 0; j < xNum; j++) {
                TOP[i][j] = HITOP;
                BOT[i][j] = HIBOT;
            }
        }

        //Initial grid values are average of station reports within the first radius
        Double rad;
        if (radList.size() > 0) {
            rad = radList.get(0);
        } else {
            rad = 4.0;
        }
        for (i = 0; i < yNum; i++) {
            y = (double) i;
            yMin = y - rad;
            yMax = y + rad;
            for (j = 0; j < xNum; j++) {
                x = (double) j;
                xMin = x - rad;
                xMax = x + rad;
                stNum = 0;
                sum = 0;
                for (int s = 0; s < pNum; s++) {
                    double val = stationData[s][2];
                    double sx = stationData[s][0];
                    double sy = stationData[s][1];
                    if (sx < 0 || sx >= xNum - 1 || sy < 0 || sy >= yNum - 1) {
                        continue;
                    }

                    if (val == unDefData || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
                        continue;
                    }

                    double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
                    if (dis > rad) {
                        continue;
                    }

                    sum += val;
                    stNum += 1;
                    if (TOP[i][j] < val) {
                        TOP[i][j] = val;
                    }
                    if (BOT[i][j] > val) {
                        BOT[i][j] = val;
                    }
                }
                if (stNum == 0) {
                    gridData[i][j] = unDefData;
                } else {
                    gridData[i][j] = sum / stNum;
                }
            }
        }

        //Perform the objective analysis
        for (int p = 0; p < irad; p++) {
            rad = radList.get(p);
            for (i = 0; i < yNum; i++) {
                y = (double) i;
                yMin = y - rad;
                yMax = y + rad;
                for (j = 0; j < xNum; j++) {
                    if (gridData[i][j] == unDefData) {
                        continue;
                    }

                    x = (double) j;
                    xMin = x - rad;
                    xMax = x + rad;
                    sum = 0;
                    double wSum = 0;
                    for (int s = 0; s < pNum; s++) {
                        double val = stationData[s][2];
                        double sx = stationData[s][0];
                        double sy = stationData[s][1];
                        if (sx < 0 || sx >= xNum - 1 || sy < 0 || sy >= yNum - 1) {
                            continue;
                        }

                        if (val == unDefData || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
                            continue;
                        }

                        double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
                        if (dis > rad) {
                            continue;
                        }

                        int i1 = (int) sy;
                        int j1 = (int) sx;
                        int i2 = i1 + 1;
                        int j2 = j1 + 1;
                        double a = gridData[i1][j1];
                        double b = gridData[i1][j2];
                        double c = gridData[i2][j1];
                        double d = gridData[i2][j2];
                        List<Double> dList = new ArrayList<>();
                        if (a != unDefData) {
                            dList.add(a);
                        }
                        if (b != unDefData) {
                            dList.add(b);
                        }
                        if (c != unDefData) {
                            dList.add(c);
                        }
                        if (d != unDefData) {
                            dList.add(d);
                        }

                        double calVal;
                        if (dList.isEmpty()) {
                            continue;
                        } else if (dList.size() == 1) {
                            calVal = dList.get(0);
                        } else if (dList.size() <= 3) {
                            double aSum = 0;
                            for (double dd : dList) {
                                aSum += dd;
                            }
                            calVal = aSum / dList.size();
                        } else {
                            double x1val = a + (c - a) * (sy - i1);
                            double x2val = b + (d - b) * (sy - i1);
                            calVal = x1val + (x2val - x1val) * (sx - j1);
                        }
                        double eVal = val - calVal;
                        double w = (rad * rad - dis * dis) / (rad * rad + dis * dis);
                        sum += eVal * w;
                        wSum += w;
                    }
                    if (wSum < 0.000001) {
                        gridData[i][j] = unDefData;
                    } else {
                        double aData = gridData[i][j] + sum / wSum;
                        gridData[i][j] = Math.max(BOT[i][j], Math.min(TOP[i][j], aData));
                    }
                }
            }
        }

        //Return
        return gridData;
    }

    /**
     * Cressman analysis - KDTree
     *
     * @param stationData station data array - x,y,value
     * @param X x array
     * @param Y y array
     * @param unDefData undefine data
     * @return grid data
     */
    public static double[][] cressman_kdTree(double[][] stationData, double[] X, double[] Y, double unDefData) {
        List<Double> radList = new ArrayList<>();
        radList.add(10.0);
        radList.add(7.0);
        radList.add(4.0);
        radList.add(2.0);
        radList.add(1.0);

        return cressman_kdTree(stationData, X, Y, unDefData, radList);
    }

    /**
     * Cressman analysis - KDTree
     *
     * @param stData station data array - x,y,value
     * @param X x array
     * @param Y y array
     * @param unDefData undefine data
     * @param radList radii list
     * @return result grid data
     */
    public static double[][] cressman_kdTree(double[][] stData, double[] X, double[] Y, double unDefData, List<Double> radList) {
        int xNum = X.length;
        int yNum = Y.length;
        int pNum = stData.length;

        double[][] gridData = new double[yNum][xNum];
        int irad = radList.size();
        int i, j;

        //Loop through each stn report and convert stn lat/lon to grid coordinates
        double xMin = X[0];
        double xMax = X[X.length - 1];
        double yMin = Y[0];
        double yMax = Y[Y.length - 1];
        double xDelt = X[1] - X[0];
        double yDelt = Y[1] - Y[0];
        double x, y;
        double sum = 0, total = 0;
        int stNum = 0;
        double[][] stationData = new double[pNum][3];
        for (i = 0; i < pNum; i++) {
            x = stData[i][0];
            y = stData[i][1];
            stationData[i][0] = (x - xMin) / xDelt;
            stationData[i][1] = (y - yMin) / yDelt;
            stationData[i][2] = stData[i][2];
            if (stationData[i][2] != unDefData) {
                total += stationData[i][2];
                stNum += 1;
            }
        }
        total = total / stNum;

        Euclidean<double[]> kdTree = new Euclidean<>(2);
        for(i = 0; i < pNum; i++){
           kdTree.addPoint(new double[]{stationData[i][0], stationData[i][1]}, stationData[i]);
        }

        //Initial the arrays
        double HITOP = -999900000000000000000.0;
        double HIBOT = 999900000000000000000.0;
        double[][] TOP = new double[yNum][xNum];
        double[][] BOT = new double[yNum][xNum];
        for (i = 0; i < yNum; i++) {
            for (j = 0; j < xNum; j++) {
                TOP[i][j] = HITOP;
                BOT[i][j] = HIBOT;
            }
        }

        //Initial grid values are average of station reports within the first radius
        double rad;
        if (radList.size() > 0) {
            rad = radList.get(0);
        } else {
            rad = 4;
        }
        for (i = 0; i < yNum; i++) {
            y = (double) i;
            yMin = y - rad;
            yMax = y + rad;
            for (j = 0; j < xNum; j++) {
                x = (double) j;
                xMin = x - rad;
                xMax = x + rad;
                stNum = 0;
                sum = 0;
                ArrayList<double[]> neighbours = kdTree.ballSearch(new double[]{x,y}, rad*rad);
                for (double[] station: neighbours) {
                    double val = station[2];
                    double sx = station[0];
                    double sy = station[1];
                    if (sx < 0 || sx >= xNum - 1 || sy < 0 || sy >= yNum - 1) {
                        continue;
                    }

                    if (val == unDefData || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
                        continue;
                    }

                    double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
                    if (dis > rad) {
                        continue;
                    }

                    sum += val;
                    stNum += 1;
                    if (TOP[i][j] < val) {
                        TOP[i][j] = val;
                    }
                    if (BOT[i][j] > val) {
                        BOT[i][j] = val;
                    }
                }

                if (stNum == 0) {
                    gridData[i][j] = unDefData;
                    //gridData[i, j] = total;
                } else {
                    gridData[i][j] = sum / stNum;
                }
            }
        }

        //Perform the objective analysis
        for (int p = 0; p < irad; p++) {
            rad = radList.get(p);
            for (i = 0; i < yNum; i++) {
                y = (double) i;
                yMin = y - rad;
                yMax = y + rad;
                for (j = 0; j < xNum; j++) {
                    if (gridData[i][j] == unDefData) {
                        continue;
                    }

                    x = (double) j;
                    xMin = x - rad;
                    xMax = x + rad;
                    sum = 0;
                    double wSum = 0;
                    ArrayList<double[]> neighbours = kdTree.ballSearch(new double[]{x,y}, rad*rad);
                    for(double[] station: neighbours){
                       double val = station[2];
                        double sx = station[0];
                        double sy = station[1];
                        if (sx < 0 || sx >= xNum - 1 || sy < 0 || sy >= yNum - 1) {
                            continue;
                        }

                        if (val == unDefData || sx < xMin || sx > xMax || sy < yMin || sy > yMax) {
                            continue;
                        }

                        double dis = Math.sqrt(Math.pow(sx - x, 2) + Math.pow(sy - y, 2));
                        if (dis > rad) {
                            continue;
                        }

                        int i1 = (int) sy;
                        int j1 = (int) sx;
                        int i2 = i1 + 1;
                        int j2 = j1 + 1;
                        double a = gridData[i1][j1];
                        double b = gridData[i1][j2];
                        double c = gridData[i2][j1];
                        double d = gridData[i2][j2];
                        List<Double> dList = new ArrayList<>();
                        if (a != unDefData) {
                            dList.add(a);
                        }
                        if (b != unDefData) {
                            dList.add(b);
                        }
                        if (c != unDefData) {
                            dList.add(c);
                        }
                        if (d != unDefData) {
                            dList.add(d);
                        }

                        double calVal;
                        if (dList.isEmpty()) {
                            continue;
                        } else if (dList.size() == 1) {
                            calVal = dList.get(0);
                        } else if (dList.size() <= 3) {
                            double aSum = 0;
                            for (double dd : dList) {
                                aSum += dd;
                            }
                            calVal = aSum / dList.size();
                        } else {
                            double x1val = a + (c - a) * (sy - i1);
                            double x2val = b + (d - b) * (sy - i1);
                            calVal = x1val + (x2val - x1val) * (sx - j1);
                        }
                        double eVal = val - calVal;
                        double w = (rad * rad - dis * dis) / (rad * rad + dis * dis);
                        sum += eVal * w;
                        wSum += w;
                    }

                    if (wSum < 0.000001) {
                        gridData[i][j] = unDefData;
                    } else {
                        double aData = gridData[i][j] + sum / wSum;
                        gridData[i][j] = Math.max(BOT[i][j], Math.min(TOP[i][j], aData));
                    }
                }
            }
        }

        //Return
        return gridData;
    }

    // </editor-fold>
    // <editor-fold desc="Others">
    /**
     * Assign point value to grid value
     *
     * @param SCoords point value array
     * @param X x coordinate
     * @param Y y coordinate
     * @param unDefData undefine value
     * @return grid data
     */
    public static double[][] assignPointToGrid(double[][] SCoords, double[] X, double[] Y,
            double unDefData) {
        int rowNum, colNum, pNum;
        colNum = X.length;
        rowNum = Y.length;
        pNum = SCoords.length;
        double[][] GCoords = new double[rowNum][colNum];
        double dX = X[1] - X[0];
        double dY = Y[1] - Y[0];
        int[][] pNums = new int[rowNum][colNum];

        for (int i = 0; i < rowNum; i++) {
            for (int j = 0; j < colNum; j++) {
                pNums[i][j] = 0;
                GCoords[i][j] = 0.0;
            }
        }

        for (int p = 0; p < pNum; p++) {
            if (doubleEquals(SCoords[p][2], unDefData)) {
                continue;
            }

            double x = SCoords[p][0];
            double y = SCoords[p][1];
            if (x < X[0] || x > X[colNum - 1]) {
                continue;
            }
            if (y < Y[0] || y > Y[rowNum - 1]) {
                continue;
            }

            int j = (int) ((x - X[0]) / dX);
            int i = (int) ((y - Y[0]) / dY);
            pNums[i][j] += 1;
            GCoords[i][j] += SCoords[p][2];
        }

        for (int i = 0; i < rowNum; i++) {
            for (int j = 0; j < colNum; j++) {
                if (pNums[i][j] == 0) {
                    GCoords[i][j] = unDefData;
                } else {
                    GCoords[i][j] = GCoords[i][j] / pNums[i][j];
                }
            }
        }

        return GCoords;
    }

    private static boolean doubleEquals(double a, double b) {
        //if (Math.Abs(a - b) < 0.000001)
        if (Math.abs(a / b - 1) < 0.00000000001) {
            return true;
        } else {
            return false;
        }
    }
    // </editor-fold>
}
//getAscGeoJsonByCIdxSim
//http://localhost:8145/api/getAscGeoJsonByCIdxSim?rowInterval=868&rowIntervalIdxNum=0&crowIntervalIdx=0&rainVal=300&SurfaceInfiltration=0.6&vegetation=0.5
/**
 * 索引从0开始
 * @param rowInterval
 * @param rowIntervalIdxNum
 * @param crowIntervalIdx
 * @return
 */
@GetMapping("/getAscGeoJsonByCIdxSim")
public String getAscGeoJsonByCIdxSim(int rowInterval,int rowIntervalIdxNum,int crowIntervalIdx,double rainVal,double SurfaceInfiltration,double vegetation) {
    String ascGeoJson = ascGeo.getAscGeoJsonByCIdxSim(rowInterval,rowIntervalIdxNum,crowIntervalIdx,rainVal,SurfaceInfiltration,vegetation);
    return ascGeoJson;
}
五、模型调用生成的结果数据为geojson

六、前端配置接入模型生成的成果geojson实现模拟洪水演进关键代码

<template>
  <div class="layerPanel">
    <div v-if="isPanelShow" class="layerPanel-content">
      <el-container>
        <el-header style="height: 30px">城市内涝积涝模拟计算</el-header>
        <el-main>
          <div>
            <div style="margin: 3px">
              <span>降雨量(mm):</span>
              <el-input v-model= 'RainVal' style="width: 90%;" clearable></el-input>
            </div>
            <div style="margin: 3px">
              <span>降雨持续时间(分钟):</span>
              <el-input v-model= 'IntervalTime' style="width: 90%;" clearable></el-input>
            </div>
            <div style="margin: 3px">
              <span>地表下渗系数:</span>
              <el-input v-model= 'SurfaceInfiltration' style="width: 90%;" clearable></el-input>
            </div>
            <div style="margin: 3px">
              <span>植被系数:</span>
              <el-input v-model= 'vegetation' style="width: 90%;" clearable></el-input>
            </div>
            <div style="margin: 3px">
              <span>模拟计算:</span>
              <el-button type="primary" round @click="simulationCalculate">计算</el-button>
              <el-button type="primary" round @click="FloodProgress">洪水演进</el-button>
            </div>
          </div>
        </el-main>
      </el-container>
    </div>
    <div class="layer-collapse" @click="layersPanelCollapse">
      <i class="layerlist"></i>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      layers: 11,
      isPanelShow: false,
      clayersInfo: [],
      opacityValue: 100,
      RainVal: 300,
      IntervalTime: 30,
      SurfaceInfiltration: 0.1,
      vegetation: 0.5,
      count:0
    }
  },
  mounted () {

  },
  methods: {
    layersPanelCollapse () {
      this.isPanelShow = !this.isPanelShow
    },
    simulationCalculate(){
      this.$emit("WaterDiffSimulation", this.RainVal,this.IntervalTime,this.SurfaceInfiltration,this.vegetation)
    },
    FloodProgress () {
      let _this = this;
      if(this.count==10){
        this.count=0
        this.$emit("FloodProgress",9)
        return
      }else {
        setTimeout(function () {
          _this.FloodProgress()
        },1000)
      }
      this.$emit("FloodProgress",this.count)
      this.count+=1
    }
  },
  props: {
    startLonLat: Object
  }
}
</script>

<style lang="less" scoped>
@import "./assets/css/index";
</style>

七、模拟展示效果(可调整降雨量、下渗系数等参数,后续版本升级加入更多参数调校率定,技术合作交流qq:2401315930)

 

 

 如果对您有所帮助,请打赏点赞支持!

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/506597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人人都应该知道的CPU缓存运行效率

提到CPU性能&#xff0c;大部分同学想到的都是CPU利用率&#xff0c;这个指标确实应该首先被关注。但是除了利用率之外&#xff0c;还有很容易被人忽视的指标&#xff0c;就是指令的运行效率。如果运行效率不高&#xff0c;那CPU利用率再忙也都是瞎忙&#xff0c;产出并不高。 …

“LSTM之父”谈AI威胁论:AI将超越人类智力,对人类不感兴趣,呼吁暂停AI是一种误导

他因在人工智能&#xff08;AI&#xff09;、深度学习和人工神经网络领域内做出的成就而知名&#xff0c;一度被称为“&#xff08;现代&#xff09;AI 之父”或“深度学习之父”。 他提出的长短期记忆网络&#xff08;LSTM&#xff09;被谷歌、苹果、亚马逊、Meta 等科技巨头…

Ims跟2/3G会议电话(Conference call)流程差异介绍

2/3G Conference call 合并(Merged)通话前,两路电话只能一路保持(Hold),一路通话(Active)。 主叫Merged操作,Hold的一路会变成Active,进入会议通话。 例如终端A跟C通话,再跟B通话,此时B就是Active状态,C从Active变成Hold状态。Merged进入会议通话后,C又从Hold变…

亚马逊关于婴儿摇篮的政策需要做的认证标准

本政策适用的婴儿摇篮 婴儿摇篮 婴儿摇篮是一种旨在为婴儿提供睡眠环境的小床。婴儿摇篮由独立支腿、固定框架或支腿、轮式底座、摇摆底座或可以相对于固定底座摇摆的底座支撑。在静止&#xff08;不摇摆或不摆动&#xff09;时&#xff0c;婴儿摇篮的睡眠表面与水平面的夹角…

ASEMI代理ADI亚德诺LT6230CS6-10#TRPBF车规级芯片

编辑-Z LT6230CS6-10#TRPBF特点&#xff1a; 低噪声电压&#xff1a;1.1nV/ √Hz 低电源电流&#xff1a;3.5mA/Amp&#xff08;最大值&#xff09; 低失调电压&#xff1a;350μV&#xff08;最大值&#xff09; 增益带宽积&#xff1a; LT6230&#xff1a;215MHz&#…

设计模式之【桥接模式】,多用组合少用继承

文章目录 一、什么是桥接模式1、使用场景2、代理、桥接、装饰器、适配器 4 种设计模式的区别3、桥接模式的优缺点4、桥接模式的四种角色 二、实例桥接模式优化代码 三、源码中使用的桥接模式1、桥接模式在JDBC中的应用 一、什么是桥接模式 桥接模式&#xff08;Bridge Pattern…

【Java 并发编程】Java 线程本地变量 ThreadLocal 详解

Java 线程本地变量 ThreadLocal 详解 1. ThreadLocal 简介2. ThreadLocal 的使用2.1 ThreadLocal 接口&#xff08;1&#xff09;initialValue()&#xff08;2&#xff09;get()&#xff08;3&#xff09;set(T value)&#xff08;4&#xff09;remove() 2.2 ThreadLocal 应用 …

springboot链接redis (Windows版本)

1。 下载链接 https://redis.io/download/ 2.下载完成之后傻瓜安装 3. 打开下载安装路径 3.输入cmd回车 4.依次执行以下命令 redis-server.exe redis-server.exe redis.windows.conf redis-cli shutdown exit redis-server.exe redis.windows.conf 可成功启动redis 5…

(五)Kubernetes - 手动部署(二进制方式安装)

Kubernetes - 手动部署 [ 4 ] 1 增加Master节点(高可用架构)1.1 部署Master2 Node1.1.1 安装Docker(Master1)1.1.2 启动Docker、设置开机自启(Master2)1.1.3 创建etcd证书目录(Master2)1.1.4 拷贝文件(Master1)1.1.5 删除证书(Master2)1.1.6 修改配置文件和主机名(Master2)1.1.…

在线一键解jsjiami.v6

在当今的互联网时代&#xff0c;JavaScript是web开发的核心技术之一。但是&#xff0c;为了保护JavaScript代码的安全性&#xff0c;很多开发者会使用JS加密技术。其中一个常用的JS加密工具是jsjiami.v6。 JS加密通过对JavaScript代码进行混淆、压缩、编码等多种操作&#xff…

使用crond定时跑脚本备份数据库

前言&#xff1a; 开发环境 服务器&#xff1a;centos 7&#xff08;腾讯云轻量服务器&#xff09; 数据库&#xff1a;mysql 5.7 一、crond是什么&#xff1f; crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程&#xff0c;与windows下的计划任务…

车载测试-can报文解析规则实例

报文解析 报文组成 一般报文主要有以下几个参数&#xff08;比较全的情况下&#xff09; 例 解析报文时主要用到的是帧ID和帧数据 帧ID 接收到的帧ID是十六进制的形式&#xff0c;由29位标识符转换的&#xff0c;目前大多数的通信协议中都直接给出了相应的帧ID&#xff0c…

一文读懂ChatGPT(全文由ChatGPT撰写)

最近ChatGPT爆火&#xff0c;相信大家或多或少都听说过ChatGPT。到底ChatGPT是什么&#xff1f;有什么优缺点呢&#xff1f; 今天就由ChatGPT自己来给大家答疑解惑~ 全文文案来自ChatGPT&#xff01; 01 ChatGPT是什么 ChatGPT是一种基于人工智能技术的自然语言处理系统&…

光耦继电器和普通继电器的区别概述

光耦继电器和普通继电器都是电气传感器元件中的一种&#xff0c;其都能够将电能转化成机械能&#xff0c;并实现各种开关控制和保护控制。但光耦继电器与普通继电器最大的区别在于其输入电路与输出电路之间通过光电转换器件&#xff0c;而不是实现物理接触。本文将从结构、工作…

为什么越来越多的设计师开始用云渲染来渲图?

为什么越来越多的设计师开始使用 云渲染&#xff1f;小编认为可以从设计师以及云渲染平台自身这2个方向分析&#xff0c;下面一起阅读云渲染干货~ 一.针对于设计师 1.出图多&#xff0c;电脑供不应求 绘图员制作完后需要渲染给甲方确认&#xff0c;甲方要求多的又着急的话边改…

MySQL---基本查询DQL(下)(排序查询、聚合查询、分组查询、分页查询、正则表达式)

1. 排序查询 语法&#xff1a; select 字段名1&#xff0c;字段名2&#xff0c;…… from 表名 order by 字段名1 [asc|desc]&#xff0c;字段名2[asc|desc]……注意&#xff1a;asc代表升序&#xff0c;desc代表降序&#xff0c;如果不写默认升序 order by用于子句中可以支持…

CM211-1-ZG_S905L 3-B_当贝纯净桌面-线刷固件包

CM211-1-ZG_S905L 3-B_当贝纯净桌面-线刷固件包-内有教程及短接点 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的没用的软件&…

python中函数与类 类中的方法-静态方法/动态方法

class student():position即令def __init__(self,name,age):self.namenameself.ageagedef eat(self):passclassmethoddef cla(cls):passstaticmethoddef sta():passpassstustudent(name张三,age12) print(stu.position)stu.sta() stu.cla()# 直接使用静态和类方法 student.cla(…

第一章 程序设计基本方法

文章目录 第一章 程序设计基本方法1 程序设计语言1.1 程序设计语言1.2 编译和解释1.3 计算机编程1、为什么学习编程&#xff1f;2、编程 2 Python语言概述2.1 Python语言的发展2.2 Python最小程序 3 Python开发环境配置3.1 Python开发环境安装1、打开官网下载2、运行安装包 3.2…

CompletableFuture使用教学

CompletableFuture使用教学 一、开始一个线程异步执行不需要返回值 通过runAsync方式 //1.不加线程池方式 CompletableFuture<Void> completableFuture CompletableFuture.runAsync(() -> {System.out.println(Thread.currentThread().getName());//停顿几秒try {…