[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分别表示设置的地图放大倍数。


相关推荐
luckys.one13 小时前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
大翻哥哥14 小时前
Python 2025:量化金融与智能交易的新纪元
开发语言·python·金融
zhousenshan16 小时前
Python爬虫常用框架
开发语言·爬虫·python
IMER SIMPLE16 小时前
人工智能-python-深度学习-经典神经网络AlexNet
人工智能·python·深度学习
CodeCraft Studio16 小时前
国产化Word处理组件Spire.DOC教程:使用 Python 将 Markdown 转换为 HTML 的详细教程
python·html·word·markdown·国产化·spire.doc·文档格式转换
专注API从业者17 小时前
Python/Java 代码示例:手把手教程调用 1688 API 获取商品详情实时数据
java·linux·数据库·python
java1234_小锋17 小时前
[免费]基于Python的协同过滤电影推荐系统(Django+Vue+sqlite+爬虫)【论文+源码+SQL脚本】
python·django·电影推荐系统·协同过滤
看海天一色听风起雨落18 小时前
Python学习之装饰器
开发语言·python·学习
XiaoMu_00118 小时前
基于Python+Streamlit的旅游数据分析与预测系统:从数据可视化到机器学习预测的完整实现
python·信息可视化·旅游
THMAIL18 小时前
深度学习从入门到精通 - 生成对抗网络(GAN)实战:创造逼真图像的魔法艺术
人工智能·python·深度学习·神经网络·机器学习·生成对抗网络·cnn