def __init__(self, ):
        self.tool = ToolKit()
        self.house_floorplan_list = []

        self.index_recombination = [4, 5, 6, 7, 0, 1, 2, 3]

        self.new_pts = []
        self.new_height = []
        self.new_height_limit = []
Beispiel #2
0
    def __init__(self, ):
        self.threshold = 1e3
        self.MAX_GRADIENT_VALUE = 90

        self.floor_line_list = []
        self.clockwise_line_list = []

        self.floor_polygon_list = []

        self.tool = ToolKit()
    def __init__(self, ):

        self.house_splitted_dict = {}
        self.room_info_list = []
        self.rest_room_info_list = []

        self.room_delete_list = []
        self.each_room_dict = {}

        self.tool = ToolKit()
Beispiel #4
0
    def __init__(self, ):

        self.room_door_list = []
        self.is_square = False

        self.tool = ToolKit()
        self.points_aligned_to_floor = PointAlignedToFloor()

        self.height_list = []
        self.height_limit_list = []
    def __init__(self):
        """init 
        """
        self.tool = ToolKit()

        self.maindoor_list = []
        self.maindoor_height_min = 0
        self.maindoor_height_max = 0

        # whether the four points of the maindoor can form a rectangle
        self.is_square = False
Beispiel #6
0
class PointAlignedToFloor(object):
    """align point to floor, first two point on the floor
    """
    def __init__(self,):
        self.tool = ToolKit()
        self.new_pts_list = []

    def align_point_to_floor(self, pts_list, floor_list):
        """align operator
        Arguments:
            floor_list [x1,y1,x2,y2,...] -- floor list
            pts_list [[x1,y1],[x2,y2],...] -- point list
        Returns:
            point list -- [[x1,y1],[x2,y2],...]
        """
        self.new_pts_list = []

        for pts in pts_list:
            # sort, anticlockwise
            pts = self.tool.calculate_convexhull(pts)

            if len(pts) > 4:
                pts = self.six_to_four(pts)
                pts = self.tool.calculate_convexhull(pts)

            is_found = False
            dis_all_list = []
            sum_dis_list = []
            new_pts = []

            for floor_line in floor_list:
                is_collinear_list = []
                dis_list = []
                first_two_point_dis = 0

                for pts_point in pts:
                    is_collinear, dis = self.tool.is_collinear_three_points(floor_line[0], floor_line[1], pts_point)
                    is_collinear_list.append(is_collinear)
                    dis_list.append(dis)
                    
                # compute sum of the smallest two dis
                smallest_num = heapq.nsmallest(2, dis_list)
                first_two_point_dis = smallest_num[0] + smallest_num[1]

                sum_dis_list.append(first_two_point_dis)
                dis_all_list.append(dis_list)

                if is_collinear_list.count(True) == 2:
                    is_found = True
                    new_pts = self.reorder_point_normal(pts, is_collinear_list)
                    if len(new_pts) == 0:
                        logger.e('find first two closest point error ...')
                        break
                    elif len(new_pts) > 0:
                        self.new_pts_list.append(new_pts)
                        break

            if not is_found:
                
                new_pts = self.reorder_point_abnormal(pts, dis_all_list, sum_dis_list)
                if len(new_pts) == 0:
                    new_floor_list = []
                    for floor_line in floor_list:
                        new_floor_list.append(floor_line[0])
                    floor_poly = Polygon(self.tool.list_to_tuple(new_floor_list))
                    new_pts = self.reorder_point_dysmorphism(pts, floor_poly)
            
                if len(new_pts) == 0:
                    logger.e('find first two closest point error ...')    
                    continue 
                else:
                    self.new_pts_list.append(new_pts)     

        if len(self.new_pts_list) != len(pts_list):
            logger.w('lost object')
        if len(self.new_pts_list) > 0:
            return True
        else:
            return False


    def reorder_point_dysmorphism(self, pts, floor_poly):

        dis_to_polyg_list = []
        for point in pts:
            if floor_poly.contains(Point(point)):
                dis_to_polyg_list.append(0.)
            else:
                dis_to_polyg_list.append(floor_poly.boundary.distance(Point(point)))

        index_list = self.find_nsmallest_num(dis_to_polyg_list, 2)

        if index_list == [0, 1] or index_list == [1, 0]:
            return [pts[1], pts[0], pts[3], pts[2]]
        elif index_list == [1, 2] or index_list == [2, 1]:
            return [pts[2], pts[1], pts[0], pts[3]]           
        elif index_list == [2, 3] or index_list == [3, 2]:
            return [pts[3], pts[2], pts[1], pts[0]]
        elif index_list == [0, 3] or index_list == [3, 0]:
            return [pts[0], pts[3], pts[2], pts[1]]
        else:
            return []


    def reorder_point_abnormal(self, pts, dis_all_list, sum_dis_list):

        small_index = sum_dis_list.index(min(sum_dis_list))

        dis_select = dis_all_list[small_index]
        smallest_two_dis = heapq.nsmallest(2, dis_select)

        index_list = []
        if smallest_two_dis[0] == smallest_two_dis[1]:
            index_list = [i for i, v in enumerate(dis_select) if v == smallest_two_dis[0]]
        else:
            index_list = [dis_select.index(smallest_two_dis[0]), dis_select.index(smallest_two_dis[1])]

        if index_list == [0, 1] or index_list == [1, 0]:
            return [pts[1], pts[0], pts[3], pts[2]]
        elif index_list == [1, 2] or index_list == [2, 1]:
            return [pts[2], pts[1], pts[0], pts[3]]           
        elif index_list == [2, 3] or index_list == [3, 2]:
            return [pts[3], pts[2], pts[1], pts[0]]
        elif index_list == [0, 3] or index_list == [3, 0]:
            return [pts[0], pts[3], pts[2], pts[1]]
        else:
            return []


    def reorder_point_normal(self, pts, is_collinear_list):
        """reorder point, if len(is_collinear_list) == 2
        Arguments:
            pts -- door/hole point(four)
            is_collinear_list -- is collinear flag
        Returns:
            door/hole list -- clockwise point, the first two point in floor
        """

        if is_collinear_list == [True, True, False, False]:
            return [pts[1], pts[0], pts[3], pts[2]]
        elif is_collinear_list == [False, True, True, False]:
            return [pts[2], pts[1], pts[0], pts[3]]
        elif is_collinear_list == [False, False, True, True]:
            return [pts[3], pts[2], pts[1], pts[0]]
        elif is_collinear_list == [True, False, False, True]:
            return [pts[0], pts[3], pts[2], pts[1]]
        else:
            return []                                        


    def six_to_four(self, six_pts_list):

        points_num = len(six_pts_list)
        x_list = []
        z_list = []
        for pts in six_pts_list:
            x_list.append(pts[0])
            z_list.append(pts[1])
        center_point = [sum(x_list)/points_num, sum(z_list)/points_num]

        dis_list = []
        for pts in six_pts_list:
            dis_list.append(self.tool.compute_distance(center_point, pts))

        max_4_index_list = self.find_nlargest_num(dis_list, 4)

        new_pts_list = []
        for idx in max_4_index_list:
            if six_pts_list[idx] not in new_pts_list:
                new_pts_list.append(six_pts_list[idx])

        return new_pts_list


    def find_nsmallest_num(self, pts_list, n):
        tmp = []
        for i in range(n):
            tmp.append(pts_list.index(min(pts_list)))
            pts_list[pts_list.index(min(pts_list))] = n
        tmp.sort()
        return tmp

    def find_nlargest_num(self, pts_list, n):
        tmp = []
        for i in range(n):
            tmp.append(pts_list.index(max(pts_list)))
            pts_list[pts_list.index(max(pts_list))] = 0
        tmp.sort()
        return tmp
Beispiel #7
0
 def __init__(self,):
     self.tool = ToolKit()
     self.new_pts_list = []
Beispiel #8
0
class FloorTool(object):
    def __init__(self, ):
        self.threshold = 1e3
        self.MAX_GRADIENT_VALUE = 90

        self.floor_line_list = []
        self.clockwise_line_list = []

        self.floor_polygon_list = []

        self.tool = ToolKit()

    def connect_line_clockwise(self, line_list):
        """converse floor line in clockwise
        
        Arguments:
            line_list {no order} -- a list of line
        
        Returns:
            [x1, y1, x2, y2, ... ] -- a list of clockwise line
        """
        self.clockwise_line_list = []
        self.floor_polygon_list = []

        # duplicate overlap line
        self.floor_line_list = self.deplicate_overlap(line_list)

        while len(self.floor_line_list) > 0:
            floor_polygon = self.generate_floor_polygon()

            if len(floor_polygon) > 0:
                if floor_polygon[0][0] == floor_polygon[-1][1]:
                    self.floor_polygon_list.append(floor_polygon)
                else:
                    continue
            else:
                break

        if len(self.floor_polygon_list) > 0:
            self.clockwise_line_list = self.find_union_polygons()

        if len(self.clockwise_line_list) > 0:
            return True
        else:
            return False

    def deplicate_overlap(self, line_list):

        angle_list = []
        for line in line_list:
            angle = abs(self.tool.comp_line_angle(line))
            if angle == 180:
                angle = 0
            if angle == 270:
                angle = 90
            angle_list.append(angle)

        angle_idx_dict = {}
        for i, angle in enumerate(angle_list):
            if angle not in angle_idx_dict.keys():
                angle_idx_dict[angle] = [i]
            else:
                angle_idx_dict[angle].append(i)

        clear_line_list = []
        for angle, idx_list in angle_idx_dict.items():
            collinear_line_list = []
            if len(idx_list) > 1:
                while len(idx_list) > 1:
                    first_line = line_list[idx_list[0]]

                    tmp_collinear_line_list = []
                    tmp_collinear_line_list.append(first_line)

                    idx_del_list = []
                    idx_del_list.append(idx_list[0])

                    for i, idx in enumerate(idx_list):
                        if i > 0:
                            line_idx = line_list[idx]
                            tmp_angle1 = self.tool.comp_line_angle(
                                [line_idx[0], first_line[0]])
                            tmp_angle2 = self.tool.comp_line_angle(
                                [line_idx[1], first_line[0]])

                            tmp_angle1 = self.angle_transfer(tmp_angle1)
                            tmp_angle2 = self.angle_transfer(tmp_angle2)

                            if tmp_angle1 != 0 and tmp_angle2 != 0:
                                tmp_angle = 0.5 * (tmp_angle1 + tmp_angle2)
                            elif tmp_angle1 == 0 and tmp_angle2 != 0:
                                tmp_angle = tmp_angle2
                            elif tmp_angle1 != 0 and tmp_angle2 == 0:
                                tmp_angle = tmp_angle1
                            else:
                                tmp_angle = 0

                            tmp_angle = self.angle_transfer(tmp_angle)

                            if tmp_angle == angle:
                                tmp_collinear_line_list.append(line_idx)
                                idx_del_list.append(idx)
                            else:
                                continue

                    if len(tmp_collinear_line_list) > 1:
                        collinear_line_list.append(tmp_collinear_line_list)

                    for idx_del in idx_del_list:
                        idx_list.remove(idx_del)

            if len(collinear_line_list) > 0:
                clear_line_list.append(collinear_line_list)

        del_line_list = []
        add_line_list = []

        if len(clear_line_list) > 0:
            for clear_line_4 in clear_line_list:
                for clear_line_3 in clear_line_4:
                    x_point_list = []
                    y_point_list = []
                    for line in clear_line_3:
                        del_line_list.append(line)
                        x_point_list.append(line[0][0])
                        x_point_list.append(line[1][0])
                        y_point_list.append(line[0][1])
                        y_point_list.append(line[1][1])

                    sorted_point_list = [
                        list(item) for item in zip(np.sort(x_point_list),
                                                   np.sort(y_point_list))
                    ]

                    new_point_list = []
                    for point in sorted_point_list:
                        if point not in new_point_list:
                            new_point_list.append(point)

                    sorted_line_list = []
                    for i in range(len(new_point_list) - 1):
                        sorted_line_list.append(
                            [new_point_list[i], new_point_list[i + 1]])

                    sorted_line_dict = {}

                    for i, sorted_line in enumerate(sorted_line_list):

                        sorted_line_dict[i] = 0
                        occur_num = 0
                        for line in clear_line_3:
                            if self.tool.is_on_line(
                                    line[0], line[1],
                                    sorted_line[0]) and self.tool.is_on_line(
                                        line[0], line[1], sorted_line[1]):
                                occur_num += 1
                        sorted_line_dict[i] = occur_num

                    for index, num in sorted_line_dict.items():
                        if num == 1:
                            add_line_list.append(sorted_line_list[index])

        for del_line in del_line_list:
            line_list.remove(del_line)
        for add_line in add_line_list:
            line_list.append(add_line)

        return line_list

    def angle_transfer(self, angle):
        if angle == 180:
            angle = 0
        if angle == 270 or angle == -90:
            angle = 90
        return angle

    def clear_line(self, line1, line2):

        if line1[0] in line2:
            line2_rest_point = line2[1 - line2.index(line1[0])]
            angle1 = self.tool.comp_line_angle([line1[1], line2_rest_point])
            angle2 = self.tool.comp_line_angle([line1[1], line1[0]])
            if (angle1 + angle2) == 0 and angle1 != angle2:
                return [line1[1], line2_rest_point]

        if line1[1] in line2:
            line2_rest_point = line2[1 - line2.index(line1[1])]
            angle1 = self.tool.comp_line_angle([line1[0], line2_rest_point])
            angle2 = self.tool.comp_line_angle([line1[0], line1[1]])
            if (angle1 + angle2) == 0 and angle1 != angle2:
                return [line1[0], line2_rest_point]

        return []

    def find_union_polygons(self):

        union_floor_line_list = []
        if len(self.floor_polygon_list) == 1:
            return [self.floor_polygon_list[0]]
        else:
            multi_polygon = []
            for floor_polygon in self.floor_polygon_list:
                polygon_one = []
                for line in floor_polygon:
                    polygon_one.append((line[0][0], line[0][1]))
                polygon_one = Polygon(polygon_one)

                if polygon_one.length < 1 or polygon_one.area < 1:
                    continue
                # print ('polygon_one: ', polygon_one)
                multi_polygon.append(polygon_one)

            # print ('multi_polygon: ', multi_polygon)
            union_polygon = cascaded_union(multi_polygon)
            multi_polygon = union_polygon

            if multi_polygon.is_empty:
                return []

            # union_floor_line_list = mapping(multi_polygon)['coordinates'][0]

            union_polygon_list = mapping(multi_polygon)['coordinates']
            union_polygon_dim = np.ndim(union_polygon_list)

            floor_poly_list = []
            if union_polygon_dim == 3:
                self.floor_line_list = []
                union_floor_line_list = union_polygon_list[0]
                for i in range(len(union_floor_line_list) - 1):
                    line = [[
                        union_floor_line_list[i][0],
                        union_floor_line_list[i][1]
                    ],
                            [
                                union_floor_line_list[i + 1][0],
                                union_floor_line_list[i + 1][1]
                            ]]
                    self.floor_line_list.append(line)
                floor_poly_list.append(self.generate_floor_polygon())
                return floor_poly_list

            else:
                for union_poly in union_polygon_list:
                    self.floor_line_list = []
                    union_floor_line_list = union_poly[0]
                    for i in range(len(union_floor_line_list) - 1):
                        line = [[
                            union_floor_line_list[i][0],
                            union_floor_line_list[i][1]
                        ],
                                [
                                    union_floor_line_list[i + 1][0],
                                    union_floor_line_list[i + 1][1]
                                ]]
                        self.floor_line_list.append(line)
                    floor_poly_list.append(self.generate_floor_polygon())

                return floor_poly_list

    def generate_floor_polygon(self):
        floor_polygon = []

        start_line = self.find_start_line(self.floor_line_list)
        if len(start_line) == 0:
            return []
        floor_polygon.append(start_line)

        if start_line in self.floor_line_list:
            self.floor_line_list.remove(start_line)
        start_line_reverse = [start_line[1], start_line[0]]
        if start_line_reverse in self.floor_line_list:
            self.floor_line_list.remove(start_line_reverse)

        while len(self.floor_line_list) > 0:
            next_line = self.find_next_line(start_line, self.floor_line_list)
            if len(next_line) > 0:
                floor_polygon.append(next_line)
                start_line = next_line
            if len(next_line) == 0:
                return floor_polygon

        return floor_polygon

    def find_next_line(self, start_line, line_list):

        next_line = []
        for line in line_list:
            if line[0] == start_line[1]:
                next_line = line
                break
            elif line[1] == start_line[1]:
                next_line = [line[1], line[0]]
                break

        if len(next_line) == 0:
            return []
        else:
            if line in self.floor_line_list:
                self.floor_line_list.remove(line)
            if next_line in self.floor_line_list:
                self.floor_line_list.remove(next_line)

        return next_line

    def find_start_line(self, line_list):
        """find start line, for sorted line in clockwise
        
        Arguments:
            line_list  -- input line list
        
        Returns:
            [x1, y1] -- the top line 
        """
        start_line = []
        # find top point
        top_point = self.find_top_point(line_list)

        # find two line through the top point
        two_top_line = []
        angles_two_top_line = []
        for line in line_list:
            if line[0] == top_point or line[1] == top_point:
                angles_two_top_line.append(self.tool.comp_line_angle(line))
                two_top_line.append(line)
                if len(two_top_line) == 2:
                    break

        if len(angles_two_top_line) == 0:
            return []

        # find the not vertical line
        top_line_not_vertical = []

        for i, angle in enumerate(angles_two_top_line):
            if angle != 90 and angle != -90:
                top_line_not_vertical = two_top_line[i]
                break
        if len(top_line_not_vertical) == 0:
            return []

        # line clockwise
        if top_line_not_vertical[0][0] > top_line_not_vertical[1][0]:
            start_line = [top_line_not_vertical[1], top_line_not_vertical[0]]
        else:
            start_line = top_line_not_vertical

        return start_line

    def find_top_point(self, line_list):
        """find the top point
        
        Returns:
            [x1, y1] -- coordinate of one of top point
        """

        top_point = []
        # find the top line, one
        x_list = []
        z_list = []
        for line in line_list:
            x_list.append(line[0][0])
            x_list.append(line[1][0])
            z_list.append(line[0][1])
            z_list.append(line[1][1])

        max_z = max(z_list)
        # num_max_z = z_list.count(max_z)
        index_max_z = z_list.index(max_z)
        top_point = [x_list[index_max_z], z_list[index_max_z]]

        return top_point
Beispiel #9
0
class BaywindowGenerator(object):
    def __init__(self, ):
        self.tool = ToolKit()
        self.baywindow_list = []
        self.baywindow_height = []
        self.baywindow_height_limit = []

    def generate_baywindow(self, baywindow_mesh_list, floor_list, room_area):
        self.baywindow_height = []
        self.baywindow_height_limit = []

        if len(baywindow_mesh_list) == 0:
            return False

        xz_list = []
        y_list = []
        xz_single_list = []
        for baywindow_mesh in baywindow_mesh_list:
            baywindow_xyz = baywindow_mesh['xyz']

            for i in range(len(baywindow_xyz) // 3):
                xz_coordinate = [
                    float(baywindow_xyz[3 * i]),
                    float(baywindow_xyz[3 * i + 2])
                ]
                y_coorinate = float(baywindow_xyz[3 * i + 1])
                if xz_coordinate not in xz_list:
                    xz_list.append(xz_coordinate)
                if y_coorinate not in y_list:
                    y_list.append(y_coorinate)

        self.baywindow_height = min(y_list)
        self.baywindow_height_limit = max(y_list)
        xz_convexhull_list = self.tool.calculate_convexhull(xz_list)

        for xz in xz_list:
            xz_single_list.append(xz[0])
            xz_single_list.append(xz[1])
        baywindow_area = self.tool.comp_area(xz_single_list)

        xz_polygon_list = Polygon(self.tool.list_to_tuple(xz_convexhull_list))

        floor_polygon_line = []
        for i in range(len(floor_list)):
            floor_polygon_line.append([
                (floor_list[i][0][0], floor_list[i][0][1]),
                (floor_list[i][1][0], floor_list[i][1][1])
            ])

        line_in_floor_list = self.find_line_in_floor(xz_polygon_list,
                                                     floor_polygon_line)

        floor_polygon_list = []
        for floor_line in floor_list:
            floor_polygon_list.append((floor_line[0]))
        floor_polygon_list = Polygon(
            self.tool.list_to_tuple(floor_polygon_list))

        # region_difference = xz_polygon_list.difference(floor_polygon_list)

        # line_in_floor_list = self.find_line_in_floor(region_difference, floor_polygon_list)
        # print ('line_in_floor_list: ', line_in_floor_list)
        # difference_polygon_list = self.find_difference_polygon(region_difference)

        line_out_floor_list = []
        for line_in_floor in line_in_floor_list:
            gap = 0.5
            out_floor_line_list_05 = []

            out_floor_line_list_05, dis_two_list = self.generate_out_floor_line(
                gap, line_in_floor, floor_polygon_list)

            line_out_floor_list.append(
                out_floor_line_list_05[dis_two_list.index(max(dis_two_list))])

        self.baywindow_list = self.clockwise_baywindow(line_in_floor_list,
                                                       line_out_floor_list)

        if len(self.baywindow_list) > 0:
            return True
        else:
            return False

    def clockwise_baywindow(self, line_in_floor_list, line_out_floor_list):

        baywindow_list = []
        for i, line_in_floor in enumerate(line_in_floor_list):
            baywindow = []

            # anticlockwise
            baywindow_convexhull = self.tool.calculate_convexhull([
                line_in_floor[0], line_in_floor[1], line_out_floor_list[i][0],
                line_out_floor_list[i][1]
            ])

            index = []
            for in_floor_pts in line_in_floor:
                for i, pts in enumerate(baywindow_convexhull):
                    if pts == [in_floor_pts[0], in_floor_pts[1]]:
                        index.append(i)

            if index == [0, 1] or index == [1, 0]:
                baywindow = [
                    baywindow_convexhull[1][0], baywindow_convexhull[1][1],
                    baywindow_convexhull[0][0], baywindow_convexhull[0][1],
                    baywindow_convexhull[3][0], baywindow_convexhull[3][1],
                    baywindow_convexhull[2][0], baywindow_convexhull[2][1]
                ]
            if index == [1, 2] or index == [2, 1]:
                baywindow = [
                    baywindow_convexhull[2][0], baywindow_convexhull[2][1],
                    baywindow_convexhull[1][0], baywindow_convexhull[1][1],
                    baywindow_convexhull[0][0], baywindow_convexhull[0][1],
                    baywindow_convexhull[3][0], baywindow_convexhull[3][1]
                ]
            if index == [2, 3] or index == [3, 2]:
                baywindow = [
                    baywindow_convexhull[3][0], baywindow_convexhull[3][1],
                    baywindow_convexhull[2][0], baywindow_convexhull[2][1],
                    baywindow_convexhull[1][0], baywindow_convexhull[1][1],
                    baywindow_convexhull[0][0], baywindow_convexhull[0][1]
                ]
            if index == [0, 3] or index == [3, 0]:
                baywindow = [
                    baywindow_convexhull[0][0], baywindow_convexhull[0][1],
                    baywindow_convexhull[3][0], baywindow_convexhull[3][1],
                    baywindow_convexhull[2][0], baywindow_convexhull[2][1],
                    baywindow_convexhull[1][0], baywindow_convexhull[1][1]
                ]

            baywindow_list.append(baywindow)

        return baywindow_list

    def generate_out_floor_line(self, gap, line_in_floor, floor_polygon_list):

        out_floor_line_list = self.tool.find_parallel_line(line_in_floor, gap)

        dis_two_list = []
        for line in out_floor_line_list:
            dis_list = []
            for point in line:
                if floor_polygon_list.contains(Point(point)):
                    dis_pt_poly = 0
                    continue
                dis_pt_poly = self.is_in_polygon(Point(point),
                                                 floor_polygon_list)
                dis_list.append(dis_pt_poly)
            dis_two_list.append(sum(dis_list))

        return out_floor_line_list, dis_two_list

    def is_in_polygon(self, pts, polygon_data):

        return polygon_data.boundary.distance(pts)

    def find_difference_polygon(self, region_difference):

        coordinates_region_difference = mapping(
            region_difference)['coordinates']
        region_dimension = np.ndim(coordinates_region_difference)

        difference_polygon_list = []
        if region_dimension == 3:
            tmp_polygon_list = []
            for polygon_list in coordinates_region_difference[0]:
                tmp_polygon_list.append([polygon_list[0], polygon_list[1]])
            difference_polygon_list.append(tmp_polygon_list)

        if region_dimension == 4:
            for region_polygon in coordinates_region_difference:
                tmp_polygon_list = []
                for polygon_list in region_polygon[0]:
                    tmp_polygon_list.append([polygon_list[0], polygon_list[1]])
                difference_polygon_list.append(tmp_polygon_list)

        return difference_polygon_list

    def find_line_in_floor(self, xz_polygon_list, floor_polygon_list):

        line_in_floor_list = []

        for floor_line in floor_polygon_list:
            line = LineString(floor_line)
            # ips = line.intersection(xz_polygon_list)
            ips = xz_polygon_list.intersection(line)

            if not ips.is_empty:
                res = mapping(ips)['coordinates']
                if np.array(res).size == 4:
                    line_in_floor_list.append(res)
        return line_in_floor_list
Beispiel #10
0
 def __init__(self, ):
     self.tool = ToolKit()
     self.baywindow_list = []
     self.baywindow_height = []
     self.baywindow_height_limit = []
Beispiel #11
0
    def __init__(self,):
        self.room_floor_list = []
        self.clockwise_line_list = []

        self.tool = ToolKit()
        self.floor_tool = FloorTool()
Beispiel #12
0
class DoorGenerator(object):
    def __init__(self, ):

        self.room_door_list = []
        self.is_square = False

        self.tool = ToolKit()
        self.points_aligned_to_floor = PointAlignedToFloor()

        self.height_list = []
        self.height_limit_list = []
        # self.height_ori_list = []

    def generate_door(self, door_mesh_list, floor_list):
        """generate all doors
        
        Arguments:
            door_mesh_list  -- mesh list
            floor_list  -- floor list
        
        Returns:
            bool -- True or False
        """
        self.room_door_list = []
        xz_less_four_points_list = []

        self.height_list = []
        self.height_limit_list = []
        if len(door_mesh_list) == 0:
            return False

        # one mesh one door
        for door_mesh in door_mesh_list:
            xyz_list = door_mesh['xyz']
            y_list = []
            xz_list = []
            for i in range(len(xyz_list) // 3):
                xz_coordinate = [
                    round(float(xyz_list[3 * i]), 3),
                    round(float(xyz_list[3 * i + 2]), 3)
                ]
                y_list.append(float(xyz_list[3 * i + 1]))
                if xz_coordinate not in xz_list:
                    xz_list.append(xz_coordinate)

            #
            if len(xz_list) < 4:
                xz_less_four_points_list.append(xz_list)
            else:
                self.room_door_list.append(
                    self.tool.calculate_convexhull(xz_list))

            # height
            if len(y_list) > 0:
                self.height_list.append(min(y_list))
                self.height_limit_list.append(max(y_list))

        # input()
        # deduplication
        self.room_door_list, self.height_list, self.height_limit_list = self.tool.point_deduplication(
            self.room_door_list, self.height_list, self.height_limit_list)
        self.room_door_list, self.height_list, self.height_limit_list = self.tool.eight_points_deduplication(
            self.room_door_list, self.height_list, self.height_limit_list)

        align_before_num = len(self.room_door_list)

        # the points on the door aligned to the floor
        if self.points_aligned_to_floor.align_point_to_floor(
                self.room_door_list, floor_list):
            self.room_door_list = self.points_aligned_to_floor.new_pts_list
        else:
            self.room_door_list = []

        align_after_num = len(self.room_door_list)

        if align_after_num == 0:
            return False

        if align_after_num < align_before_num:
            logger.w('door is getting less')

        new_room_door_list = []
        for room_door in self.room_door_list:
            if not self.tool.is_square(room_door):
                # self.room_door_list = []
                # return False
                continue

            new_room_door_list.append([
                room_door[0][0], room_door[0][1], room_door[1][0],
                room_door[1][1], room_door[2][0], room_door[2][1],
                room_door[3][0], room_door[3][1]
            ])

        self.room_door_list = new_room_door_list

        if len(self.room_door_list) > 0:
            return True
        else:
            return False
Beispiel #13
0
 def __init__(self, ):
     self.at_house_info_dict = []
     self.tool = ToolKit()
class ConnectInfoGenerator(object):
    def __init__(self, ):
        self.tool = ToolKit()
        self.house_floorplan_list = []

        self.index_recombination = [4, 5, 6, 7, 0, 1, 2, 3]

        self.new_pts = []
        self.new_height = []
        self.new_height_limit = []

        # self.draw_room = VisHouse()

    def generate_connect_info(self, house_info_list):

        self.new_pts = []
        self.new_height = 0
        self.new_height_limit = 0

        for i, room_info in enumerate(house_info_list):
            room_floor_list = room_info['floor']

            for j, room_info_other in enumerate(house_info_list):
                if i != j:
                    other_door_list = room_info_other['door']
                    other_hole_list = room_info_other['hole']
                    other_window_list = room_info_other['window']

                    other_door_height_list = room_info_other['door_height']
                    other_hole_height_list = room_info_other['hole_height']
                    other_window_height_list = room_info_other['window_height']

                    other_door_height_limit_list = room_info_other[
                        'door_height_limit']
                    other_hole_height_limit_list = room_info_other[
                        'hole_height_limit']
                    other_window_height_limit_list = room_info_other[
                        'window_height_limit']

                    # doorinfo
                    if len(other_door_list) > 0:
                        for k, other_door in enumerate(other_door_list):
                            if self.is_belong_this_room(
                                    other_door, room_floor_list,
                                    other_door_height_list[k],
                                    other_door_height_limit_list[k]):
                                room_info['door'].append(self.new_pts)
                                room_info['door_height'].append(
                                    self.new_height)
                                room_info['door_height_limit'].append(
                                    self.new_height_limit)
                    # holeinfo
                    if len(other_hole_list) > 0:
                        for k, other_hole in enumerate(other_hole_list):
                            if self.is_belong_this_room(
                                    other_hole, room_floor_list,
                                    other_hole_height_list[k],
                                    other_hole_height_limit_list[k]):
                                room_info['hole'].append(self.new_pts)
                                room_info['hole_height'].append(
                                    self.new_height)
                                room_info['hole_height_limit'].append(
                                    self.new_height_limit)

                    # windowinfo
                    if len(other_window_list) > 0:
                        for k, other_window in enumerate(other_window_list):
                            if self.is_belong_this_room(
                                    other_window, room_floor_list,
                                    other_window_height_list[k],
                                    other_window_height_limit_list[k]):
                                room_info['window'].append(self.new_pts)
                                room_info['window_height'].append(
                                    self.new_height)
                                room_info['window_height_limit'].append(
                                    self.new_height_limit)

            # remove duplicate information
            room_info['door'], room_info['door_height'], room_info[
                'door_height_limit'] = self.remove_duplicate(
                    room_info['door'], room_info['door_height'],
                    room_info['door_height_limit'])
            room_info['hole'], room_info['hole_height'], room_info[
                'hole_height_limit'] = self.remove_duplicate(
                    room_info['hole'], room_info['hole_height'],
                    room_info['hole_height_limit'])
            room_info['window'], room_info['window_height'], room_info[
                'window_height_limit'] = self.remove_duplicate(
                    room_info['window'], room_info['window_height'],
                    room_info['window_height_limit'])
            # print ('room-type: ', room_info['room'])
            # self.draw_room.draw_room(room_info)

        # add connect information
        house_info_list = self.compute_connect_relationship(house_info_list)

        return house_info_list

    def compute_connect_relationship(self, house_info_list):

        for i, room_info in enumerate(house_info_list):

            # doorinfo
            room_info['doorinfo'] = self.add_connect_info(
                i, room_info, house_info_list, 'door')
            # holeinfo
            room_info['holeinfo'] = self.add_connect_info(
                i, room_info, house_info_list, 'hole')
            # windowinfo
            room_info['windowinfo'] = self.add_connect_info(
                i, room_info, house_info_list, 'window')

        return house_info_list

    def add_connect_info(self, idx, room_info, house_info_list, type_='door'):

        obj_info_list = []
        if len(room_info[type_]) > 0:
            for obj_ in room_info[type_]:
                obj_info_dict = {}
                for jdx, other_room_info in enumerate(house_info_list):
                    if idx != jdx:
                        if self.is_appeared(obj_, other_room_info[type_]):
                            obj_info_dict['pts'] = obj_
                            obj_info_dict['to'] = other_room_info['room']
                            obj_info_list.append(obj_info_dict)

        return obj_info_list

    def is_appeared(self, pts, other_pts_list):
        one_pts = [pts[0], pts[1], pts[2], pts[3]]
        for other_pts in other_pts_list:
            another_pts = [
                other_pts[4], other_pts[5], other_pts[6], other_pts[7]
            ]
            if one_pts == another_pts:
                return True

        return False

    def remove_duplicate(self, v_list, height_list, height_limit_list):
        new_v_list = []
        new_height_list = []
        new_height_limit_list = []
        for i, v in enumerate(v_list):
            if v not in new_v_list:
                new_v_list.append(v)
                new_height_list.append(height_list[i])
                new_height_limit_list.append(height_limit_list[i])
        return new_v_list, new_height_list, new_height_limit_list

    def is_belong_this_room(self, pts, room_floor_list, height, height_limit):

        self.new_pts = []
        self.new_height = 0
        self.new_height_limit = 0

        pts_parallel_line_list = self.tool.find_parallel_line(
            [[pts[4], pts[5]], [pts[6], pts[7]]], 0.1)

        floor_polygon = self.tool.floor_to_polygon(room_floor_list).buffer(
            0.0005)

        for line in pts_parallel_line_list:
            for point in line:
                if floor_polygon.contains(Point(point)):
                    for idx in self.index_recombination:
                        self.new_pts.append(pts[idx])
                        self.new_height = height
                        self.new_height_limit = height_limit
                    return True
        return False
class HouseSplitter(object):
    def __init__(self, ):

        self.house_splitted_dict = {}
        self.room_info_list = []
        self.rest_room_info_list = []

        self.room_delete_list = []
        self.each_room_dict = {}

        self.tool = ToolKit()

    def split_house(self, house_info_dict):

        # self.house_info = house_info_dict

        # single
        # only find entrydoor
        entry_room = house_info_dict['maindoor'][0]
        floorplan = house_info_dict['floorplan']

        # print ('entry_room: ', entry_room)

        self.room_delete_list = []
        self.each_room_dict = {}

        # find entry-room
        for i, room_info in enumerate(floorplan):
            if len(room_info['door']) == 0 and len(room_info['hole']) == 0:
                self.room_delete_list.append(i)

            if room_info['room'] == entry_room['room']:
                self.each_room_dict['maindoor'] = [entry_room]
                self.each_room_dict['floorplan'] = [room_info]

                self.room_info_list.append(self.each_room_dict)
                self.room_delete_list.append(i)

        # delete entry-room
        self.rest_room_info_list = self.delete_room(self.room_delete_list,
                                                    floorplan)
        self.room_delete_list = []

        pre_door_list = self.each_room_dict['floorplan'][0]['door']
        pre_hole_list = self.each_room_dict['floorplan'][0]['hole']

        pre_doorhole_list = []
        if len(pre_door_list) > 0:
            for door in pre_door_list:
                pre_doorhole_list.append(door)
        if len(pre_hole_list) > 0:
            for hole in pre_hole_list:
                pre_doorhole_list.append(hole)

        # self.rest_room_info_list
        while len(self.rest_room_info_list) > 0:
            new_doorhole_list = []
            new_doorhole_list = self.split_room(pre_doorhole_list)
            pre_doorhole_list = new_doorhole_list

            if len(new_doorhole_list) == 0:
                # stairwell
                break
                # pass

        # self.house_splitted_dict['rooms'] = self.room_info_list
        self.house_splitted_dict = self.room_info_list

        if len(self.room_info_list) > 0:
            return True
        else:
            return False

    def split_room(self, pre_doorhole_list):

        new_doorhole_list = []
        self.room_delete_list = []

        if len(pre_doorhole_list) > 0 and len(self.rest_room_info_list) > 0:
            for i, room_info in enumerate(self.rest_room_info_list):
                door_list = room_info['door']
                hole_list = room_info['hole']

                door_height_list = room_info['door_height']
                door_height_limit_list = room_info['door_height_limit']

                hole_height_list = room_info['hole_height']
                hole_height_limit_list = room_info['hole_height_limit']

                # delete door
                if len(door_list) > 0:
                    for x, door in enumerate(door_list):
                        if self.is_appeared(door, pre_doorhole_list):

                            next_doorhole = self.find_next_room(room_info)
                            if len(next_doorhole) > 0:
                                for pts in next_doorhole:
                                    new_doorhole_list.append(pts)

                            maindoor_dict = {}
                            maindoor_dict['room'] = room_info['room']
                            maindoor_dict['point'] = door

                            angle, direction = self.tool.compute_door_hole_direction(
                                door)
                            maindoor_dict['angle'] = angle
                            maindoor_dict['direction'] = direction
                            maindoor_dict['height'] = door_height_list[x]
                            maindoor_dict[
                                'height_limit'] = door_height_limit_list[x]

                            self.each_room_dict = {}
                            self.each_room_dict['maindoor'] = [maindoor_dict]
                            self.each_room_dict['floorplan'] = [room_info]

                            self.room_info_list.append(self.each_room_dict)
                            self.room_delete_list.append(i)

                # delete hole
                if len(hole_list) > 0:
                    for x, hole in enumerate(hole_list):
                        if self.is_appeared(hole, pre_doorhole_list):

                            next_doorhole = self.find_next_room(room_info)
                            if len(next_doorhole) > 0:
                                for pts in next_doorhole:
                                    new_doorhole_list.append(pts)

                            maindoor_dict = {}
                            maindoor_dict['room'] = room_info['room']
                            maindoor_dict['point'] = hole

                            angle, direction = self.tool.compute_door_hole_direction(
                                hole)
                            maindoor_dict['angle'] = angle
                            maindoor_dict['direction'] = direction
                            maindoor_dict['height'] = hole_height_list[x]
                            maindoor_dict[
                                'height_limit'] = hole_height_limit_list[x]

                            self.each_room_dict = {}
                            self.each_room_dict['maindoor'] = [maindoor_dict]
                            self.each_room_dict['floorplan'] = [room_info]

                            self.room_info_list.append(self.each_room_dict)
                            self.room_delete_list.append(i)

        if len(self.room_delete_list) > 0:
            self.rest_room_info_list = self.delete_room(
                self.room_delete_list, self.rest_room_info_list)

        return new_doorhole_list

    def find_next_room(self, room_info):
        doorhole_info = []
        if len(room_info['door']) > 0:
            for door in room_info['door']:
                doorhole_info.append(door)
        if len(room_info['hole']) > 0:
            for hole in room_info['hole']:
                doorhole_info.append(hole)

        return doorhole_info

    def is_appeared(self, obj_pts, pts_list):

        obj_coordnite = [obj_pts[0], obj_pts[1], obj_pts[2], obj_pts[3]]
        for ori_pts in pts_list:
            if [ori_pts[4], ori_pts[5], ori_pts[6],
                    ori_pts[7]] == obj_coordnite:
                return True
        return False

    def delete_room(self, delete_list, floorplan):

        del_reverse_list = sorted(set(delete_list), reverse=True)
        for idx in del_reverse_list:
            floorplan.pop(idx)

        return floorplan
class MainDoorGenerator(object):
    """maindoor generator
    
    Arguments:
        maindoor_list -- maindoor coordnate list
        maindoor_height_min -- minimum height of the maindoor
        maindoor_height_max -- maximum height of the maindoor
        is_sauqre -- whether the point of maindoor is a square
    
    Returns:
        bool -- True or False
    """
    def __init__(self):
        """init 
        """
        self.tool = ToolKit()

        self.maindoor_list = []
        self.maindoor_height_min = 0
        self.maindoor_height_max = 0

        # whether the four points of the maindoor can form a rectangle
        self.is_square = False

    def get_maindoor(self, maindoor_dict, mesh_dict):
        """get maindoor list
        
        Arguments:
            maindoor_dict {dict} -- from json_information_acquirer
            mesh_dict {dict} -- from json_information_acquirer

        Returns:
            bool -- True or False
        """
        # logger.i('start generate maindoor ... ')
        try:
            maindoor_tmp_dict = {}
            maindoor_ref_list = []
            for roomID, doorinfo in maindoor_dict.items():
                maindoor_tmp_dict['roomId'] = roomID
                maindoor_ref_list = doorinfo['ref']
        except Exception as e:
            return False

        maindoor_mesh_list = []
        for mesh_uid, mesh_value in mesh_dict.items():
            if mesh_uid in maindoor_ref_list:
                maindoor_mesh_list.append(mesh_value)

        if len(maindoor_mesh_list) == 0:
            logger.e('cannot find maindoor mesh')
            return False

        y_list = []
        xz_list = []
        for maindoor_mesh in maindoor_mesh_list:
            maindoor_xyz_list = maindoor_mesh['xyz']
            maindoor_faces_list = maindoor_mesh['faces']

            for i in range(len(maindoor_xyz_list) // 3):
                y_list.append(float(maindoor_xyz_list[3 * i + 1]))
                xz_list.append([
                    round(float(maindoor_xyz_list[3 * i]), 3),
                    round(float(maindoor_xyz_list[3 * i + 2]), 3)
                ])

        self.maindoor_height_min = round(min(y_list), 3)
        self.maindoor_height_max = round(max(y_list), 3)

        self.maindoor_list = self.tool.calculate_convexhull(xz_list)

        if len(self.maindoor_list) < 4:
            return False
        elif len(self.maindoor_list) == 4:
            return self.tool.is_square(self.maindoor_list)
        else:
            return False

    def determine_entrydoor(self, house_info_list):

        maindoor_dict = {}
        maindoor_dict['point'] = []
        is_found = False
        for room_info in house_info_list:
            door_info_list = room_info['door']
            for door_info in door_info_list:
                if [door_info[0], door_info[1]] in self.maindoor_list:
                    maindoor_dict['point'] = door_info
                    maindoor_dict['room'] = room_info['room']
                    is_found = True
                    break
            if is_found:
                break
        if len(maindoor_dict['point']) > 0:
            angle, direction = self.tool.compute_door_hole_direction(
                maindoor_dict['point'])
            maindoor_dict['angle'] = angle
            maindoor_dict['direction'] = direction
            maindoor_dict['height'] = self.maindoor_height_min
            maindoor_dict['height_limit'] = self.maindoor_height_max

            return maindoor_dict
        else:
            return {}
Beispiel #17
0
class FloorGenerator(object):
    def __init__(self,):
        self.room_floor_list = []
        self.clockwise_line_list = []

        self.tool = ToolKit()
        self.floor_tool = FloorTool()


    def generate_floor(self, floor_mesh_list, room_id):
        """generate floor info
        
        Arguments:
            floor_mesh_list {list} -- floor mesh
        
        Returns:
            bool -- True or False
        """
        if len(floor_mesh_list) == 0:
            logger.e('%s does not have floor.' % room_id)
            return False
        
        xz_faces_list = []
        floor_mesh_list = self.tool.mesh_duplicate(floor_mesh_list)

        for floor_mesh in floor_mesh_list:

            xz_list = []
            floor_mesh_xyz = floor_mesh['xyz']
            floor_mesh_faces = floor_mesh['faces']

            for i in range(len(floor_mesh_xyz)//3):
                xz_list.append([float(floor_mesh_xyz[3*i]), float(floor_mesh_xyz[3*i+2])])

            if len(xz_list) == 0:
                return False

            xz_sorted_list = []
            for index in floor_mesh_faces:
                xz_sorted_list.append(xz_list[index])

            for point in xz_sorted_list:
                xz_faces_list.append(point)

        grid_to_line_list = []
        for i in range(len(xz_faces_list)//3):
            
            if (xz_faces_list[3*i][0] == xz_faces_list[3*i+1][0] and xz_faces_list[3*i][0] == xz_faces_list[3*i+2][0]) or (xz_faces_list[3*i][1] == xz_faces_list[3*i+1][1] and xz_faces_list[3*i][1] == xz_faces_list[3*i+2][1]):
                continue

            grid_line_list = self.tool.grid_to_multi_line(xz_faces_list[3*i], xz_faces_list[3*i+1], xz_faces_list[3*i+2])

            if grid_line_list[0][0] == grid_line_list[0][1] or grid_line_list[1][0] == grid_line_list[1][1] or grid_line_list[2][0] == grid_line_list[2][1]:
                continue

            grid_to_line_list.append(grid_line_list[0])
            grid_to_line_list.append(grid_line_list[1])
            grid_to_line_list.append(grid_line_list[2])

        # count the number of occurrences of a line segment. if ==1, conserve, else, ignore
        once_line_list = self.tool.find_once_line(grid_to_line_list)
        once_line_list = self.tool.line_deduplication(once_line_list)

        if len(once_line_list) == 0:
            return False

        self.clockwise_line_list = []
        # connect all segments clockwise
        if self.floor_tool.connect_line_clockwise(once_line_list):
            if len(self.floor_tool.clockwise_line_list) == 1:
                self.clockwise_line_list = self.floor_tool.clockwise_line_list[0]
            else:
                logger.w('%s appeared multi floor' % room_id)
                idx_len_list = []
                for line_list in self.floor_tool.clockwise_line_list:
                    idx_len_list.append(len(line_list))
                self.clockwise_line_list = self.floor_tool.clockwise_line_list[idx_len_list.index(max(idx_len_list))]
        else:
            logger.e('%s cannot generate floor: %d' % (room_id, len(self.clockwise_line_list)))
            return False

        if self.tool.is_closed(self.clockwise_line_list):
            self.clockwise_line_list = self.tool.merge_line(self.clockwise_line_list)
            self.clockwise_line_list = self.tool.overlap_line_deduplication(self.clockwise_line_list)
        else:
            return False

        return True