• [Model.py 02] 地图按比例放大的实现


    要求:实现地图按比例放大

    分析:考虑到地图放大过程中需要保留河流道路这些物体的相对位置关系,这里选择将河流和道路这些物体的坐标矩阵合并成terrain_matrix并对这个合并后的矩阵进行缩放处理。放大后的矩阵,根据矩阵中标记的物体位置,更新各自物体的放大矩阵。

    思路:对于地图按比例放大,借用图片放大的思路,使用最近邻插值的方式,填充放大后产生的空隙。

    实现:

    补充大小调整参数self.zoomScale

    _init_self.grid初始化之前,补充大小调整参数:self.zoomScale_init_函数修改部分的代码如下:

        def __init__(self, N=10, K=0, width=50, height=102,
                     civil_info_exchange=True, model_layer=-1, is_fired=False, is_flood=True, count=0):
            self.warning_UI = ""  # 警示信息
            self.resizeScale=3 # parameter using to control the scale of the map
    
    • 1
    • 2
    • 3
    • 4

    _init_函数中补充地图放大、更新代码

            # 将安全通道坐标加载到地图中
            self.draw_environment(self.pos_exits)
            # 创建坐标空间
            self.graph = path_finding.create_graph(self)
    
    
            self.combine_matrices()
            # To rescale the terrain map size after combination.
            self.resize_matrices(self.resizeScale)
            self.separate_matrix() # update different object matrix from the resized matrix.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    地图放大函数resize_matrices的定义

        def resize_matrices(self, degree):
            """
            Resize the terrain and constituent matrices while maintaining aspect ratio.
    
            :param degree: New rescaling degree.
            """
            scaling_factor = (degree, degree)
    
            # Resize the main terrain matrix
            self.terrain_matrix = zoom(self.terrain_matrix, scaling_factor, order=0)
            # order=1 for bilinear interpolation and 0 for nearest-neighbor interpolation.
            # This change will ensure that your matrices' integer values are preserved during the resizing process.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    放大后更新其他物体的坐标矩阵函数separate_matrix

        def separate_matrix(self):
            """
            Separate the combined terrain matrix into individual feature matrices.
    
            Each matrix should represent one feature (e.g., river, road) with 1s where the feature exists
            and 0s where it doesn't.
            """
            # Identify all unique features in the terrain matrix, excluding 0 (empty)
            unique_features = np.unique(self.terrain_matrix)
    
            # Define a mapping from feature codes to the corresponding class attributes
            feature_mapping = {
                1: 'river_matrix',
                2: 'road_matrix',
                3: 'wall_matrix',
                4: 'indoor_matrix',
                5: 'exits_matrix',
                6: 'pillar_matrix',
                7: 'ditch_matrix'
            }
    
            # Initialize each matrix as an array of zeros
            for matrix_name in feature_mapping.values():
                setattr(self, matrix_name, np.zeros_like(self.terrain_matrix))
    
            # For each feature, populate the corresponding matrix
            for feature in unique_features:
                if feature == 0:
                    continue  # Skip the 'empty' feature
    
                matrix_name = feature_mapping.get(feature)
                if not matrix_name:
                    continue  # Skip if the feature is not recognized
    
                # Update the corresponding matrix directly
                feature_matrix = np.where(self.terrain_matrix == feature, 1, 0)
                setattr(self, matrix_name, feature_matrix)
    
            # At this point, each feature matrix (e.g., self.river_matrix) has been updated directly
            # No need to return anything since we're modifying the class attributes directly
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    补充:放大后地图的可视化脚本

    请与单独的.py文件中运行。

    # It's assumed you have executed the following installation command in your local environment:
    # !pip install datashader
    
    import datashader as ds
    import datashader.transfer_functions as tf
    import pandas as pd
    
    # Load and prepare the data
    from matplotlib import pyplot as plt
    
    file_path = 'G:\\terrain_matrix3.csv'
    data = pd.read_csv(file_path)
    
    # Calculate the aspect ratio of the original data
    num_rows, num_cols = data.shape  # Assuming 'data' is your DataFrame
    aspect_ratio = num_cols / num_rows
    
    # Ensure column headers are consistent and represent coordinates or indexing
    # If headers are numeric: good; if not, you might want to set headers as a range of numbers representing columns
    data.columns = range(len(data.columns))
    
    # Resetting the index to turn it into a column for melting
    data = data.reset_index()
    
    # Melting the data (now 'X' should be consistently numeric)
    melted_data = data.melt(id_vars=['index'], var_name='X', value_name='Value')
    melted_data['Y'] = melted_data['index']
    melted_data.drop(columns=['index'], inplace=True)
    
    # Convert 'X' and 'Y' to numeric values, coercing errors (i.e., non-numeric values are set as NaN)
    melted_data['X'] = pd.to_numeric(melted_data['X'], errors='coerce')
    melted_data['Y'] = pd.to_numeric(melted_data['Y'], errors='coerce')
    
    # Handle or remove any rows with NaN if necessary (created by 'coerce')
    melted_data.dropna(subset=['X', 'Y'], inplace=True)
    
    # Define the dimensions for the canvas
    plot_width = 800
    plot_height = int(plot_width / aspect_ratio)  # Maintain the aspect ratio of the original data
    
    # Set up the canvas with the correct aspect ratio
    canvas = ds.Canvas(plot_width=plot_width, plot_height=plot_height)
    
    # Aggregating data into a grid
    agg = canvas.points(melted_data, 'X', 'Y', ds.mean('Value'))
    
    # Creating an image by coloring the aggregated data
    img = tf.shade(agg, cmap=['lightblue', 'darkblue'], how='linear')
    
    # Convert the Datashader image to a format that can be displayed by matplotlib
    img_to_plot = tf.shade(agg, cmap=['lightblue', 'darkblue'], how='linear')
    img_plt = tf.set_background(img_to_plot, 'white')
    
    # Display the image using matplotlib
    plt.imshow(img_plt.to_pil())
    plt.axis('off')  # Optional: this removes the axes for a cleaner look
    plt.title('Presentation of the rescaling map data(3X).')
    
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    以下是可视化脚本的输出案例。其中,2X和3X分别表示设置的地图放大倍数。

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    windows11 安装cnpm 报错 Error: EPERM: operation not permitted 没权限
    科技“蝶变”,两轮电动车下一个五年的“新动力”
    异步编程和asyncio
    07-prometheus的自定义监控-pushgateway工具组件
    springboot url路径映射本地静态资源
    C++类和对象-多态->案例1计算器类、案例2制作饮品、案例3电脑组装需求分析和电脑组装具体实现
    Vim使用
    金字塔原理
    FSOD论文阅读 - 基于卷积和注意力机制的小样本目标检测
    HDFS总结
  • 原文地址:https://blog.csdn.net/m0_51952128/article/details/133918747