[Model.py 03]Modification for creating terrain matrix3.

Modification for wall and ditch matrix

Presentation:
[Model.py 03]Modification for creating terrain matrix3._第1张图片

Modification

Delete: Except for ditch_matrix, all varibles and code relevant with ditch are deleted.

Modify:

For initial_positon

                if pos_type == 'wall':
                    '''
                        Applying: 1 to self.wall_matrix along the route 
                        from the start point(start_x,start_y) to end point (end_x,end_y) 
                    '''
                    self.apply_matrix_dots(start_x, start_y, end_x, end_y, 'wall')

For apply_matrix_dots

        if attri=='wall':
            '''
                Considering wall is initialized with two dots, finding out all the dots lying in the rectangular first, 
                then acquiring all the dots lying in the outer line. 
            '''
            rectangle_dots=self.get_coordinates_in_range((start_x,start_y),(end_x,end_y))
            ditch=self.get_rectangle_coordinates(start_x-1,start_y-1,end_x+1,end_y+1)
            for x,y in rectangle_dots:
                self.wall_matrix[x][y]=1
            for x,y in ditch:
                self.ditch_matrix[x][y]=1

Full code

# 获取坐标文件
import numpy as np
import pandas as pd

class Evaluation():




    def __init__(self):
        # 获取偏移转化参数
        x_shifting, y_shifting, x_scale, y_scale = 2850, 1500, 10, 10
        road_positions_filename = f'./road.xlsx'
        wall_positions_filename = f'./east_station.xlsx'
        river_positions_filename = f'./river3.xlsx'
        self.width,self.height=350,240
        self.ditch_matrix = np.zeros((self.width, self.height))  # initializing ditch matrix
        self.wall_matrix = np.zeros((self.width, self.height))  # initializing wall matrix
        self.initial_position(wall_positions_filename, x_shifting, y_shifting, x_scale, y_scale, 'wall')

        ditch_df = pd.DataFrame(self.ditch_matrix)
        ditch_df.to_csv('.\\ditch_matrix.csv', index=False, header=False)
        ditch_df = pd.DataFrame(self.wall_matrix)
        ditch_df.to_csv('.\\wall_matrix.csv', index=False, header=False)


    def initial_position(self, file_name, x_shifting, y_shifting, x_scale, y_scale, pos_type):
        """
        参数:file_name(文件路径名字), pos_type(坐标类型)
        进行坐标转换,初始化墙、内门以及出口坐标
        """
        # 读取文件
        if pos_type == 'road':
            df = pd.read_excel(file_name, header=None)
            tuple_list = []

            # 遍历每一行
            for index, row in df.iterrows():
                tuple_row = []
                col_index = 1  # 初始列索引
                # 在每行内部,每次读取两列数据,直到读完所有列
                while col_index < len(row):
                    data1 = row.iloc[col_index]  # 第一列的数据
                    data2 = row.iloc[col_index + 1]  # 第二列的数据
                    if pd.notna(data1) and pd.notna(data2):
                        tuple_row.append((data1, data2))
                    col_index += 2  # 更新列索引,跳过已读取的两列
                if tuple_row:
                    tuple_list.append(tuple_row)
            for sublist in tuple_list:
                # 遍历每一行
                maxy = -100000
                col_index = 0
                while col_index + 1 < len(sublist):
                    # 获取两列数据
                    data1 = sublist[col_index]
                    data2 = sublist[col_index + 1]
                    start_x, start_y, end_x, end_y = data1[0], data1[1], data2[0], data2[1]

                    end_x += x_shifting
                    end_x /= x_scale
                    # end_x *= self.grid.width
                    end_x = round(end_x)
                    end_y += y_shifting
                    end_y /= y_scale
                    # end_y *= self.grid.height
                    end_y = round(end_y)
                    start_x += x_shifting
                    start_x /= x_scale
                    start_x = round(start_x)
                    start_y += y_shifting
                    start_y /= y_scale
                    start_y = round(start_y)
                    self.roads.append({"start_x": start_x, "end_x": end_x, "start_y": start_y, "end_y": end_y})
                    '''
                        Applying 1 to self.road_matrix along the route 
                        from the start point(star_x,star_y) to end point (end_x,end_x) 
                    '''
                    self.apply_matrix_dots(start_x, start_y, end_x, end_y, 'road')
                    col_index += 1
        elif pos_type == "river":
            df = pd.read_excel(file_name)
            num = df['x1'].notna().sum()
            print(pos_type, "数量:", num)
            # 坐标变化
            for i in range(num):
                start_x, start_y = df['x1'][i], df['y1'][i]
                start_x += x_shifting
                start_x /= x_scale
                start_x = round(start_x)
                # align with roads
                start_x = start_x - 38
                start_y += y_shifting
                start_y /= y_scale
                start_y = round(start_y)
                # align with roads
                start_y = start_y + 28
                self.stream_pos.append((start_x, start_y))
                if i > 0:
                    '''
                        Applyiing 1 to self.river_matrix along the route 
                        from the start point(start0_x,start0_y) to end point (start_x,start_y) 
                    '''
                    self.apply_matrix_dots(start0_x, start0_y, start_x, start_y, 'river')
                start0_x, start0_y = start_x, start_y
            num2 = df['x2'].notna().sum()
            print(pos_type, "add 数量:", num2)
            # 坐标变化
            for i in range(num2):
                start_x, start_y = df['x2'][i], df['y2'][i]
                start_x += x_shifting
                start_x /= x_scale
                start_x = round(start_x)
                # align with roads
                start_x = start_x - 38
                start_y += y_shifting
                start_y /= y_scale
                start_y = round(start_y)
                # align with roads
                start_y = start_y + 28
                self.stream_pos2.append((start_x, start_y))
                if i > 0:
                    '''
                        Applying 1 to self.river_matrix along the route 
                        from the start point(start0_x,start0_y) to end point (start_x,start_y) 
                    '''
                    self.apply_matrix_dots(start0_x, start0_y, start_x, start_y, 'river')
                start0_x, start0_y = start_x, start_y
        else:
            df = pd.read_excel(file_name)
            num = len(df['x1'])
            print(pos_type, "数量:", num)
            # 坐标变化
            for i in range(num):
                if pos_type == 'wall':
                    start_x, start_y, end_x, end_y = df['x1'][i], df['y1'][i], df['x2'][i], df['y2'][i]
                    end_x += x_shifting
                    end_x /= x_scale
                    end_x = round(end_x)
                    end_y += y_shifting
                    end_y /= y_scale
                    end_y = round(end_y)

                else:
                    start_x, start_y = df['x1'][i], df['y1'][i]

                start_x += x_shifting
                start_x /= x_scale

                start_x = round(start_x)
                start_y += y_shifting
                start_y /= y_scale

                start_y = round(start_y)

                if pos_type == 'wall':
                    '''
                        Applying: 1 to self.wall_matrix along the route 
                        from the start point(start_x,start_y) to end point (end_x,end_y) 
                    '''
                    self.apply_matrix_dots(start_x, start_y, end_x, end_y, 'wall')
                elif pos_type == 'indoor':
                    self.indoors.append((start_x, start_y))
                    if i > 0:
                        '''
                            Applying 1 to self.indoor_matrix along the route 
                            from the start point(start0_x,start0_y) to end point (start_x,start_y) 
                        '''
                        self.apply_matrix_dots(start0_x, start0_y, start_x, start_y, 'indoor')
                    start0_x, start0_y = start_x, start_y
                elif pos_type == 'exit':
                    if start_x == end_x:
                        for i in range(start_y, end_y + 1):
                            self.pos_exits.append((start_x, i))
                            # 920 apply coordinates to exits_matrix
                            self.exits_matrix[start_x][i] = 1
                    elif start_y == end_y:
                        for i in range(start_x, end_x + 1):
                            self.pos_exits.append((i, start_y))
                            # 920 apply coordinates to exits_matrix
                            self.exits_matrix[i][start_y] = 1
                    else:
                        continue
                elif pos_type == "pillar":
                    pillar_positions = {"start_x": start_x, "end_x": end_x, "start_y": start_y, "end_y": end_y}
                    self.pillars.append(pillar_positions)
                    '''
                        Applying 1 to self.pillar_matrix along the route 
                        from the start point(start_x,start_y) to end point (end_x,end_y) 
                    '''
                    self.apply_matrix_dots(start_x, start_y, end_x, end_y, 'pillar')
                else:
                    pass
                    # self.water_initial_pos.append((start_x, start_y))
    def get_rectangle_coordinates(self, x1, y1, x2, y2):
        '''
        acquiring all the dots of outer line which is composed with two dots(x1,y1) (x2,y2)
        :param x1:
        :param y1:
        :param x2:
        :param y2:
        :return:
        '''
        # Ensure (x1, y1) is the bottom-left corner and (x2, y2) is the top-right corner
        x_min = min(x1, x2)
        x_max = max(x1, x2)
        y_min = min(y1, y2)
        y_max = max(y1, y2)

        # Calculate coordinates of the four corners
        bottom_left = (x_min, y_min)
        bottom_right = (x_max, y_min)
        top_left = (x_min, y_max)
        top_right = (x_max, y_max)

        # Generate points along each edge
        left_edge = [(x_min, y) for y in range(y_min, y_max + 1)]
        right_edge = [(x_max, y) for y in range(y_min, y_max + 1)]
        bottom_edge = [(x, y_min) for x in range(x_min, x_max + 1)]
        top_edge = [(x, y_max) for x in range(x_min, x_max + 1)]

        # Combine all the points
        all_points = [bottom_left, bottom_right, top_left, top_right]
        all_points.extend(left_edge)
        all_points.extend(right_edge)
        all_points.extend(bottom_edge)
        all_points.extend(top_edge)

        return list(set(all_points))

    def get_coordinates_in_range(self, bottom_left, top_right):
        '''
        find the rectangle between the two dots
        :param bottom_left:(x0,y0) left dot
        :param top_right:(x1,y1) right dot
        :return: a list containing all dots within the rectangle which is composed with two dots
        '''
        coordinates = []
        for x in range(bottom_left[0], top_right[0] + 1):
            for y in range(bottom_left[1], top_right[1] + 1):
                coordinates.append((x, y))
        return coordinates

    def apply_matrix_dots(self, start_x, start_y, end_x, end_y, attri):
        '''
        Applying Bresenham's line algorithm to find out all the points along the route and updating all the location on matrix as 1.
        Args:
            start_x:
            start_y:
            end_x:
            end_y:
            attri: Utilized for determining which matrix should be modified.

        Returns:

        '''

        # Get the points for the line between start and end
        if attri!='wall':
            points = self.bresenham_line(start_x, start_y, end_x, end_y)
        if attri=='road':
            # Update the road_matrix for each point on the line
            for x, y in points:
                self.road_matrix[x][y] = 1
        if attri=='river':
            for x, y in points:
                self.river_matrix[x][y] = 1
        if attri=='wall':
            '''
                Considering wall is initialized with two dots, finding out all the dots lying in the rectangular first, 
                then acquiring all the dots lying in the outer line. 
            '''
            rectangle_dots=self.get_coordinates_in_range((start_x,start_y),(end_x,end_y))
            ditch=self.get_rectangle_coordinates(start_x-1,start_y-1,end_x+1,end_y+1)
            for x,y in rectangle_dots:
                self.wall_matrix[x][y]=1
            for x,y in ditch:
                self.ditch_matrix[x][y]=1
        if attri=='indoor':
            # Question: what's the meaning of indoor? The output of inoor matrix contains nothing.
            for x,y in points:
                self.indoor_matrix[x][y]=1
        if attri=='pillar':
            # Question: what's the meaning of pillar? The output of pillar matrix contains nothing.
            for x,y in points:
                self.pillar_matrix[x][y]=1

    def bresenham_line(self,x0, y0, x1, y1):
        """Bresenham's Line Algorithm
        Produces a list of tuples from start and end points
        This  is used to determine the points of an n-dimensional
        raster that should be selected in order to form a close
        approximation to a straight line between two points.
        """
        points = []
        is_steep = abs(y1 - y0) > abs(x1 - x0)
        if is_steep:
            x0, y0 = y0, x0
            x1, y1 = y1, x1
        swapped = False
        if x0 > x1:
            x0, x1 = x1, x0
            y0, y1 = y1, y0
            swapped = True
        dx = x1 - x0
        dy = y1 - y0
        error = int(dx / 2.0)
        y_step = 1 if y0 < y1 else -1
        y = y0
        for x in range(x0, x1 + 1):
            coord = (y, x) if is_steep else (x, y)
            points.append(coord)
            error -= abs(dy)
            if error < 0:
                y += y_step
                error += dx
        if swapped:
            points.reverse()
        return points

if __name__ == '__main__':
    evauation=Evaluation()

你可能感兴趣的:(python)