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 create_hollowed_facade(surface_facade, window): b_facade_cmpd = fetch.topo2topotype(construct.boolean_difference(surface_facade, window)) hole_facade = fetch.topo_explorer(b_facade_cmpd, "face")[0] hollowed_facade = construct.simple_mesh(hole_facade) # Clean small triangles: this is a despicable source of error hollowed_facade_clean = [x for x in hollowed_facade if calculate.face_area(x) > 1E-3] return hollowed_facade_clean, hole_facade
def create_windows(surface, wwr, ref_pypt): scaler = math.sqrt(wwr) return fetch.topo2topotype( modify.uniform_scale(surface, scaler, scaler, scaler, ref_pypt))
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