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

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

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

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

实现:

补充大小调整参数self.zoomScale

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

python 复制代码
    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

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

python 复制代码
        # 将安全通道坐标加载到地图中
        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.

地图放大函数resize_matrices的定义

python 复制代码
    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.

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

python 复制代码
    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

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

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

python 复制代码
# 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()

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


相关推荐
K2I-20 分钟前
UCI中Steel Plates Faults不平衡数据集处理
python
蓑笠翁00120 分钟前
Django REST Framework 全面指南:从模型到完整API接口开发
后端·python·django
感谢地心引力1 小时前
【Python】基于 PyQt6 和 Conda 的 PyInstaller 打包工具
数据库·python·conda·pyqt·pyinstaller
xiaohanbao092 小时前
Transformer架构与NLP词表示演进
python·深度学习·神经网络
love530love3 小时前
【笔记】 Podman Desktop 中部署 Stable Diffusion WebUI (GPU 支持)
人工智能·windows·笔记·python·容器·stable diffusion·podman
程序员晚枫3 小时前
Python 3.14正式发布!这5大新特性太炸裂了
python
先做个垃圾出来………4 小时前
SortedList
python
这里有鱼汤4 小时前
从DeepSeek到Kronos,3个原因告诉你:Kronos如何颠覆传统量化预测
后端·python·aigc
晓宜4 小时前
Java25 新特性介绍
java·python·算法
深栈4 小时前
机器学习:决策树
人工智能·python·决策树·机器学习·sklearn