示例#1
0
def burn_buildings(geometry, elevation_map):
    if geometry.has_z:
        # remove elevation - we'll add it back later by intersecting with the topography
        point_list_2D = ((a, b) for (a, b, _) in geometry.exterior.coords)
    else:
        point_list_2D = geometry.exterior.coords
    point_list_3D = [(a, b, 0) for (a, b) in point_list_2D]  # add 0 elevation

    # creating floor surface in pythonocc
    face = construct.make_polygon(point_list_3D)
    # get the midpt of the face
    face_midpt = calculate.face_midpt(face)

    terrain_tin = elevation_map.generate_tin()
    # make shell out of tin_occface_list and create OCC object
    terrain_shell = construct.make_shell(terrain_tin)
    terrain_intersection_curves = IntCurvesFace_ShapeIntersector()
    terrain_intersection_curves.Load(terrain_shell, 1e-6)

    # project the face_midpt to the terrain and get the elevation
    inter_pt, inter_face = calc_intersection(terrain_intersection_curves,
                                             face_midpt, (0, 0, 1))

    # reconstruct the footprint with the elevation
    loc_pt = (inter_pt.X(), inter_pt.Y(), inter_pt.Z())
    face = fetch.topo2topotype(modify.move(face_midpt, loc_pt, face))
    return face
def burn_buildings(geometry, terrain_intersection_curves):
    if geometry.has_z:
        # remove elevation - we'll add it back later by intersecting with the topography
        point_list_2D = ((a, b) for (a, b, _) in geometry.exterior.coords)
    else:
        point_list_2D = geometry.exterior.coords
    point_list_3D = [(a, b, 0) for (a, b) in point_list_2D]  # add 0 elevation

    # creating floor surface in pythonocc
    face = construct.make_polygon(point_list_3D)
    # get the midpt of the face
    face_midpt = calculate.face_midpt(face)

    # project the face_midpt to the terrain and get the elevation
    inter_pt, inter_face = calc_intersection(terrain_intersection_curves,
                                             face_midpt, (0, 0, 1))

    # reconstruct the footprint with the elevation
    try:
        loc_pt = (inter_pt.X(), inter_pt.Y(), inter_pt.Z())
    except:
        raise ValueError(
            'ERROR: this usually happens when buildings do not overlap with the terrain, try to check if this is the case'
        )
    face = fetch.topo2topotype(modify.move(face_midpt, loc_pt, face))
    return face
def calc_windows_walls(facade_list, wwr):
    window_list = []
    wall_list = []
    normals_win = []
    normals_wall = []
    for surface_facade in facade_list:
        ref_pypt = calculate.face_midpt(surface_facade)
        standard_normal = py3dmodel.calculate.face_normal(surface_facade) # to avoid problems with fuzzy normals
        # offset the facade to create a window according to the wwr
        if 0.0 < wwr < 1.0:
            # for window
            window = create_windows(surface_facade, wwr, ref_pypt)
            window_list.append(window)
            normals_win.append(standard_normal)
            # for walls
            hollowed_facade, hole_facade = create_hollowed_facade(surface_facade, window)  # accounts for hole created by window
            wall_list.extend(hollowed_facade)
            normals_wall.extend([standard_normal]*len(hollowed_facade))

        elif wwr == 1.0:
            window_list.append(surface_facade)
            normals_win.append(standard_normal)
        else:
            wall_list.append(surface_facade)
            normals_wall.append(standard_normal)

    return window_list, wall_list, normals_win, normals_wall
def calc_solid(face_footprint, range_floors, flr2flr_height):

    # create faces for every floor and extrude the solid
    moved_face_list = []
    for floor_counter in range_floors:
        dist2mve = floor_counter * flr2flr_height
        # get midpt of face
        orig_pt = calculate.face_midpt(face_footprint)
        # move the pt 1 level up
        dest_pt = modify.move_pt(orig_pt, (0, 0, 1), dist2mve)
        moved_face = modify.move(orig_pt, dest_pt, face_footprint)
        moved_face_list.append(moved_face)

    # make checks to satisfy a closed geometry also called a shell

    vertical_shell = construct.make_loft(moved_face_list)
    vertical_face_list = fetch.topo_explorer(vertical_shell, "face")
    roof = moved_face_list[-1]
    footprint = moved_face_list[0]
    all_faces = []
    all_faces.append(footprint)
    all_faces.extend(vertical_face_list)
    all_faces.append(roof)
    building_shell_list = construct.sew_faces(all_faces)

    # make sure all the normals are correct (they are pointing out)
    bldg_solid = construct.make_solid(building_shell_list[0])
    bldg_solid = modify.fix_close_solid(bldg_solid)

    ##dO this to visualize progress while debugging!:
    #face_list = fetch.geom_explorer(bldg_solid, "face")
    # edges = calculate.visualise_face_normal_as_edges(face_list,5)
    # construct.visualise([face_list,edges],["WHITE","BLACK"])
    return bldg_solid
示例#5
0
    def cal_face_list(floor_counter):
        dist2mve = floor_counter * floor_to_floor_height
        # get midpt of face
        orig_pt = calculate.face_midpt(face_footprint)
        # move the pt 1 level up
        dest_pt = modify.move_pt(orig_pt, (0, 0, 1), dist2mve)
        moved_face = modify.move(orig_pt, dest_pt, face_footprint)

        return moved_face
def calc_windows_walls(facade_list, wwr, data_processed):
    window_list = []
    wall_list = []
    normals_win = []
    normals_wall = []
    wall_intersects = []
    number_intersecting_solids = len(
        data_processed.potentially_intersecting_solids)
    range_of_surroundings_building_solid_list = range(
        number_intersecting_solids)
    for surface_facade in facade_list:
        # get coordinates of surface
        ref_pypt = calculate.face_midpt(surface_facade)
        standard_normal = py3dmodel.calculate.face_normal(
            surface_facade)  # to avoid problems with fuzzy normals

        # evaluate if the surface intersects any other solid (important to erase non-active surfaces in the building
        # simulation model)
        data_processed.point_to_evaluate = py3dmodel.modify.move_pt(
            ref_pypt, standard_normal, 0.1)  # tol of 10cm

        if number_intersecting_solids > 0:
            # flag weather it intersects a surrounding geometry
            intersects = np.vectorize(calc_intersection_face_solid)(
                range_of_surroundings_building_solid_list, data_processed)
            intersects = sum(intersects)
        else:
            intersects = 0

        if intersects > 0:  # the face intersects so it is a wall
            wall_list.append(surface_facade)
            normals_wall.append(standard_normal)
            wall_intersects.append(1)
        else:
            # offset the facade to create a window according to the wwr
            if 0.0 < wwr < 1.0:
                # for window
                window = create_windows(surface_facade, wwr, ref_pypt)
                window_list.append(window)
                normals_win.append(standard_normal)
                # for walls
                hollowed_facade, hole_facade = create_hollowed_facade(
                    surface_facade,
                    window)  # accounts for hole created by window
                wall_intersects.extend([intersects] * len(hollowed_facade))
                wall_list.extend(hollowed_facade)
                normals_wall.extend([standard_normal] * len(hollowed_facade))

            elif wwr == 1.0:
                window_list.append(surface_facade)
                normals_win.append(standard_normal)
            else:
                wall_list.append(surface_facade)
                normals_wall.append(standard_normal)
                wall_intersects.append(intersects)

    return window_list, wall_list, normals_win, normals_wall, wall_intersects
示例#7
0
def building_2d_to_3d(citygml_writer, zone_shp_path, district_shp_path,
                      tin_occface_list, height_col, nfloor_col):
    """
    This script extrudes buildings from the shapefile and creates intermediate floors.

    :param citygml_writer: the cityGML object to which the buildings are gonna be created.
    :param district_shp_path: path to the shapefile to be extruded of the district
    :param tin_occface_list: the faces of the terrain, to be used to put the buildings on top.
    :param height_col:
    :param nfloor_col:
    :return:
    """
    # read district shapefile and names of buildings of the zone of analysis
    district_building_records = gdf.from_file(district_shp_path).set_index(
        'Name')
    district_building_names = district_building_records.index.values
    zone_building_names = gdf.from_file(zone_shp_path)['Name'].values

    #make shell out of tin_occface_list and create OCC object
    terrain_shell = construct.sew_faces(tin_occface_list)[0]
    terrain_intersection_curves = IntCurvesFace_ShapeIntersector()
    terrain_intersection_curves.Load(terrain_shell, 1e-6)
    bsolid_list = []

    #create the buildings in 3D
    for name in district_building_names:
        height = float(district_building_records.loc[name, height_col])
        nfloors = int(district_building_records.loc[name, nfloor_col])

        # Make floors only for the buildings of the zone of interest
        # for the rest just consider one high floor.
        # simplify geometry tol =1 for buildings of interest, tol = 5 for surroundings
        if name in zone_building_names:
            range_floors = range(nfloors + 1)
            floor_to_floor_height = height / nfloors
            geometry = district_building_records.ix[name].geometry.simplify(
                1, preserve_topology=True)
        else:
            range_floors = [0, 1]
            floor_to_floor_height = height
            geometry = district_building_records.ix[name].geometry.simplify(
                5, preserve_topology=True)

        point_list_2D = list(geometry.exterior.coords)
        point_list_3D = [(a, b, 0)
                         for (a, b) in point_list_2D]  # add 0 elevation

        #creating floor surface in pythonocc
        face = construct.make_polygon(point_list_3D)
        #get the midpt of the face
        face_midpt = calculate.face_midpt(face)

        #project the face_midpt to the terrain and get the elevation
        inter_pt, inter_face = calc_intersection(terrain_intersection_curves,
                                                 face_midpt, (0, 0, 1))

        loc_pt = (inter_pt.X(), inter_pt.Y(), inter_pt.Z())
        #reconstruct the footprint with the elevation
        face = fetch.topo2topotype(modify.move(face_midpt, loc_pt, face))

        moved_face_list = []
        for floor_counter in range_floors:
            dist2mve = floor_counter * floor_to_floor_height
            #get midpt of face
            orig_pt = calculate.face_midpt(face)
            #move the pt 1 level up
            dest_pt = modify.move_pt(orig_pt, (0, 0, 1), dist2mve)
            moved_face = modify.move(orig_pt, dest_pt, face)
            moved_face_list.append(moved_face)

        #loft all the faces and form a solid
        vertical_shell = construct.make_loft(moved_face_list)
        vertical_face_list = fetch.topo_explorer(vertical_shell, "face")
        roof = moved_face_list[-1]
        footprint = moved_face_list[0]
        all_faces = []
        all_faces.append(footprint)
        all_faces.extend(vertical_face_list)
        all_faces.append(roof)
        bldg_shell_list = construct.sew_faces(all_faces)

        # make sure all the normals are correct (they are pointing out)
        if bldg_shell_list:
            bldg_solid = construct.make_solid(bldg_shell_list[0])
            bldg_solid = modify.fix_close_solid(bldg_solid)
            bsolid_list.append(bldg_solid)
            occface_list = fetch.topo_explorer(bldg_solid, "face")
            geometry_list = gml3dmodel.write_gml_srf_member(occface_list)
            citygml_writer.add_building("lod1", name, geometry_list)

    return bsolid_list