建立一个数字高程模型(DEM),同时控制山的数量及其邻近性

2024-09-18 22:56:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是得到一个二维浮标阵列(即矩阵),它可以可视化为一个数字高程模型(即等高线图),具有平滑的等高线,如下图所示,前提是我能够控制生成多少白山以及它们之间的距离当我运行脚本的时候。你知道吗

白色的山脉表示CSV文件中包含大于0.9的值的单元格簇,如色标所示。在图中,我们看到两座山被面积分割,数值低于0.9。 contours 下面是我的完整代码和详细注释,我使用卷积滤波器来创建这样的图像:

import numpy as np
import pandas as pd
from scipy import signal
import plotly
import plotly.graph_objs as go


def rndmtx():
    """Generate random 2d-array as a digital elevation model."""

    nx = 100
    ny = 100
    dem1 = np.random.rand(nx, ny)
    # Save array to csv file befor Gaussian filter.
    # Comment the next two lines if reading from the csv file.
    dafr = pd.DataFrame(dem1)
    dafr.to_csv('G_dem1.csv', header=False, index=False)

    # Uncomment the next two lines to read from csv file.
    # dafr = pd.read_csv('G_dem1.csv', header=None)
    # dem1 = dafr.values

    # Apply the first Gaussian filter.
    sizex = 5  # The less sizex and sizey the more highlands.
    sizey = 5  # The more sizex and sizey the more water.
    x, y = np.mgrid[-sizex:sizex+1, -sizey:sizey+1]
    scale = 0.33  # The more scale the bigger the difference in elevation.
    g = np.exp(-scale*(x**2/sizex+y**2/sizey))
    filter1 = g/g.sum()  # Normalise the Gaussian function.

    dem_smooth = signal.convolve(dem1, filter1, mode='valid')
    # Rescale so it lies between 0 and 1.
    dem_smooth = ((dem_smooth - dem_smooth.min())
                  / (dem_smooth.max() - dem_smooth.min()))

    # Apply the second Gaussian filter to make the boundaries smoother.
    sizex = 5
    sizey = 5
    x, y = np.mgrid[-sizex:sizex+1, -sizey:sizey+1]
    g = np.exp(-0.33*(x**2/sizex+y**2/sizey))
    filter2 = g/g.sum()

    dem_smooth1 = signal.convolve(dem_smooth, filter2, mode='valid')
    dem_smooth1 = ((dem_smooth1 - dem_smooth1.min())
                   / (dem_smooth1.max() - dem_smooth1.min()))

    return dem_smooth1

# Get the raw random array of the digital elevation model
#   and assign it to the variable.
contour_xy = rndmtx()

# Save the array into CSV file in the working directory.
df = pd.DataFrame(contour_xy)
df.to_csv('last_data.csv', header=False, index=False)

data = [
    go.Contour(
        z=contour_xy,
        colorscale=[
            [0, 'rgb(0, 161, 233)'], [0.28, 'rgb(0, 161, 233)'],
            [0.28, 'rgb(29, 210, 108)'], [0.50, 'rgb(29, 210, 108)'],
            [0.50, 'rgb(141, 232, 130)'], [0.65, 'rgb(141, 232, 130)'],
            [0.65, 'rgb(254, 254, 152)'], [0.75, 'rgb(254, 254, 152)'],
            [0.75, 'rgb(192, 182, 122)'], [0.82, 'rgb(192, 182, 122)'],
            [0.82, 'rgb(142, 110, 92)'], [0.88, 'rgb(142, 110, 92)'],
            [0.88, 'rgb(171, 147, 142)'], [0.93, 'rgb(171, 147, 142)'],
            [0.93, 'rgb(227, 219, 217)'], [0.97, 'rgb(227, 219, 217)'],
            [0.97, 'rgb(255, 255, 255)'], [1, 'rgb(255, 255, 255)']
        ],
    ),
]

layout = go.Layout(
    yaxis=dict(
        autorange='reversed'
    )
)

figure = go.Figure(data=data, layout=layout)
plotly.offline.plot(figure, filename='dem.html')

每次运行脚本时,我都会得到一个唯一的随机数字数组。你知道吗

如何控制要生成的白山的数量和距离?

例如,现在我想在地块上放置10座白山,然后我只想要2座山,依此类推。你知道吗

目前,我使用蛮力算法,最终建立了一个与所需数量的山脉,但我无法设置具体的坐标山之间的距离控制阴谋。你知道吗

慷慨的回答和指出正确的方向是高度赞赏的。喜欢玩代码!你知道吗


Tags: csvthetoimportgoasnprgb
1条回答
网友
1楼 · 发布于 2024-09-18 22:56:14

其中一个笨重的解决方案是,在高斯过滤之前,用大于0.9的值填充CSV文件中的一些单元格簇,例如,所有单元格,如下图所示。你知道吗

这只是一个CSV文件在Excel中打开应用的色阶功能。左边是随机矩阵。在右边,您可以看到我尝试设置四个大小相等的6x4单元格,所有单元格都包含一个值“1”。 matrices 应用卷积滤波器后,我得到以下结果: contour-try 这不好,因为我只有两座山和两个棕色高地。另外,还有很多水。我想要尽可能少的水。你知道吗

如果你能指出其他技巧的话,我不介意从头开始重写剧本。你知道吗

更新

多亏了社区,我终于找到了一个稳定的解决方案: 建立散点图,然后将其转换为等高线。你知道吗

见问题Convert Scatter to Contour, every dot turns into a highland

相关问题 更多 >