def convert(shpfile_list, citygml): #get the building footprints building_list = [] for shpfile in shpfile_list: buildings = shp2citygml.get_buildings(shpfile) if buildings: building_list.extend(buildings) print "done with getting buildings" print "TOTAL NUMBER OF BUILDINGS:", len(building_list) total_perror_list = [] total_constr_list = [] total_trpst_bldg_list = [] total_inacc_buildings = [] total_build_up_area = 0 #read the shapefiles for shpfile in shpfile_list: sf = shapefile.Reader(shpfile) shapeRecs = sf.shapeRecords() shapetype = shapeRecs[0].shape.shapeType #get the project CRS of the shapefile epsg_num = "EPSG:" + shp2citygml.get_shpfile_epsg(shpfile) field_name_list = shp2citygml.get_field_name_list(sf) #shapetype 1 is point, 3 is polyline, shapetype 5 is polygon #if it is a point file it must be recording the location of the bus stops and subway stations if shapetype == 1: trpst_bldg_list = convert_ptshpfile(field_name_list, shapeRecs, citygml) total_trpst_bldg_list.extend(trpst_bldg_list) if shapetype == 3: convert_polylineshpfile(field_name_list, shapeRecs, citygml) if shapetype == 5: shp_perror_list, shp_constr_list, shp_inacc_buildings, total_flr_area = convert_polygonshpfile( field_name_list, shapeRecs, citygml, building_list) if shp_perror_list: total_perror_list.extend(shp_perror_list) if shp_constr_list: total_constr_list.extend(shp_constr_list) if shp_inacc_buildings: total_inacc_buildings.extend(shp_inacc_buildings) total_build_up_area = total_build_up_area + total_flr_area print "NUMBER OF BUILDINGS IN CONSTRUCTION:", len(total_constr_list) print "NUMBER OF MRT/LRT STATIONS:", len(total_trpst_bldg_list) print "NUMBER OF BUILDINGS WITH LEVEL INFORMATION:", len(total_perror_list) print "TOTAL BUILD UP AREA:", total_build_up_area print "MEAN:", (sum(total_perror_list)) / (len(total_perror_list)) print "MAX:", max(total_perror_list) print "MIN:", min(total_perror_list) print "MEDIAN:", findmedian(total_perror_list) print "NUMBER OF INACCURATE BUILDINGS:", len(total_inacc_buildings)
def read_sf_polyline(sf_filepath): sf = shapefile.Reader(sf_filepath) attrib_name_list = shp2citygml.get_field_name_list(sf)[1:] shapeRecs = sf.shapeRecords() shpatt_list = [] for rec in shapeRecs: poly_atts = rec.record pypolygon_list2d = shp2citygml.get_geometry(rec) if pypolygon_list2d: pypolygon_list3d = shp2citygml.pypolygon_list2d_2_3d( pypolygon_list2d, 0.0) for polyline in pypolygon_list3d: shpatt = shapeattributes.ShapeAttributes() shpatt.set_shape(polyline) att2shpatt(shpatt, attrib_name_list, poly_atts) shpatt_list.append(shpatt) return shpatt_list
pypt2d = pypt_list2d[0] pypt3d = (pypt2d[0], pypt2d[1], 0.0) #create a rectangle boundary occrec = py3dmodel.construct.make_rectangle(bdimx, bdimy) #move the rec to pypt3d m_occrec = py3dmodel.modify.move((0, 0, 0), pypt3d, occrec) m_occrec = py3dmodel.fetch.topo2topotype(m_occrec) #=========================================================================================== #GET ALL THE SHAPES WITHIN THIS BOUNDARY #=========================================================================================== sf = shapefile.Reader(shpfile) shapeRecs = sf.shapeRecords() attrib_name_list = shp2citygml.get_field_name_list(sf) height_index = attrib_name_list.index(height_attrib) - 1 solid_list = [] for rec in shapeRecs: poly_attribs = rec.record #print poly_attribs height = poly_attribs[height_index] pypolygon_list2d = shp2citygml.get_geometry(rec) if pypolygon_list2d: pypolygon_list3d = shp2citygml.pypolygon_list2d_2_3d( pypolygon_list2d, 0.0) occface_list = shp2citygml.shp_pypolygon_list3d_2_occface_list( pypolygon_list3d) for occface in occface_list: if height > 0: occsolid = py3dmodel.construct.extrude(occface, (0, 0, 1),
def convert(self): import time QtGui.QApplication.processEvents() self.progress = 0 self.update_bar() self.params.param('Result View').param('Progress').setValue("") #get the shpfile height_attrib = str( self.params.param('Height Attrib').param( 'Height Attribute').value()) bldg_footprint_shp_file = self.params.param('Shape File').param( 'Shapefile Loaded').value() dtm_tif_file = self.params.param('DTM File').param( 'DTM Loaded').value() result_directory = self.params.param('Result Directory').param( 'Result Directory Chosen').value() #viewer = self.params.param('Interactive View').param('Viewer On').value() self.timer.timeout.connect(self.update_bar) self.timer.start(20) #=========================================================================================== #FUNCTIONS #=========================================================================================== def raster_reader(input_terrain_raster): ''' __author__ = "Paul Neitzel, Kian Wee Chen" __copyright__ = "Copyright 2016, Architecture and Building Systems - ETH Zurich" __credits__ = ["Paul Neitzel", "Jimeno A. Fonseca"] __license__ = "MIT" __version__ = "0.1" __maintainer__ = "Daren Thomas" __email__ = "*****@*****.**" __status__ = "Production" ''' # read raster records raster_dataset = gdal.Open(input_terrain_raster) band = raster_dataset.GetRasterBand(1) a = band.ReadAsArray(0, 0, raster_dataset.RasterXSize, raster_dataset.RasterYSize) (y_index, x_index) = np.nonzero(a >= 0) (upper_left_x, x_size, x_rotation, upper_left_y, y_rotation, y_size) = raster_dataset.GetGeoTransform() x_coords = x_index * x_size + upper_left_x + ( x_size / 2) # add half the cell size y_coords = y_index * y_size + upper_left_y + ( y_size / 2) # to centre the point return [(x, y, z) for x, y, z in zip(x_coords, y_coords, a[y_index, x_index])] #=========================================================================================== #THE RESULT FILES #=========================================================================================== north_facade_collada_filepath = os.path.join(result_directory, "north_facade.dae") south_facade_collada_filepath = os.path.join(result_directory, "south_facade.dae") east_facade_collada_filepath = os.path.join(result_directory, "east_facade.dae") west_facade_collada_filepath = os.path.join(result_directory, "west_facade.dae") roof_collada_filepath = os.path.join(result_directory, "roof.dae") footprint_collada_filepath = os.path.join(result_directory, "footprint.dae") terrain_collada_filepath = os.path.join(result_directory, "terrain.dae") try: #=========================================================================================== #CONSTRUCT THE TERRAIN #=========================================================================================== time1 = time.clock() display_2dlist = [] #read the tif terrain file and create a tin from it pyptlist = raster_reader(dtm_tif_file) QtGui.QApplication.processEvents() self.params.param('Result View').param('Progress').setValue( "Constructing the Terrain ... ...") self.progress = 10 tin_occface_list = py3dmodel.construct.delaunay3d(pyptlist) terrain_shell = py3dmodel.construct.sew_faces(tin_occface_list)[0] #=========================================================================================== #EXTRUDE THE BUILDING #=========================================================================================== sf = shapefile.Reader(bldg_footprint_shp_file) shapeRecs = sf.shapeRecords() attrib_name_list = shp2citygml.get_field_name_list(sf) height_index = attrib_name_list.index(height_attrib) - 1 solid_list = [] face_list = [] QtGui.QApplication.processEvents() self.params.param('Result View').param('Progress').setValue( "Extruding the Buildings ... ...") self.progress = 20 cnt = 0 for rec in shapeRecs: QtGui.QApplication.processEvents() poly_attribs = rec.record height = poly_attribs[height_index] pypolygon_list2d = shp2citygml.get_geometry(rec) if pypolygon_list2d: pypolygon_list3d = shp2citygml.pypolygon_list2d_2_3d( pypolygon_list2d, 0.0) occface_list = shp2citygml.shp_pypolygon_list3d_2_occface_list( pypolygon_list3d) for occface in occface_list: if height > 0: occsolid = py3dmodel.construct.extrude( occface, (0, 0, 1), height) solid_list.append(occsolid) face_list.append(occface) cnt += 1 #move all the faces to a very high elevation and project them down onto the terrain so that we know where to place the buildings face_cmpd = py3dmodel.construct.make_compound(face_list) f_midpt = py3dmodel.calculate.get_centre_bbox(face_cmpd) loc_pt = [f_midpt[0], f_midpt[1], 1000] t_face_cmpd = py3dmodel.modify.move(f_midpt, loc_pt, face_cmpd) face_list2 = py3dmodel.fetch.topo_explorer(t_face_cmpd, "face") #face_list2 = face_list2[0:10] msolid_list = [] QtGui.QApplication.processEvents() self.params.param('Result View').param('Progress').setValue( "Placing the Buildings ... ...") self.progress = 50 fcnt = 0 for face2 in face_list2: pyptlist = py3dmodel.fetch.points_frm_occface(face2) #print "NUM PTS:", len(pyptlist) z_list = [] for pypt in pyptlist: QtGui.QApplication.processEvents() interpt, interface = py3dmodel.calculate.intersect_shape_with_ptdir( terrain_shell, pypt, (0, 0, -1)) if interpt: z = interpt[2] z_list.append(z) if z_list: min_z = min(z_list) #print min_z face = face_list[fcnt] face_midpt = py3dmodel.calculate.face_midpt(face) bldg_loc_pt = [face_midpt[0], face_midpt[1], min_z] bsolid = solid_list[fcnt] m_bsolid = py3dmodel.modify.move(face_midpt, bldg_loc_pt, bsolid) msolid_list.append(m_bsolid) fcnt += 1 self.params.param('Result View').param('Progress').setValue( "Classfying the Building Surfaces ... ...") QtGui.QApplication.processEvents() self.progress = 70 total_facade_list = [] total_roof_list = [] total_footprint_list = [] for solid in msolid_list: QtGui.QApplication.processEvents() facade_list, roof_list, footprint_list = urbangeom.identify_building_surfaces( solid) total_facade_list.extend(facade_list) total_roof_list.extend(roof_list) total_footprint_list.extend(footprint_list) n_list, s_list, e_list, w_list = urbangeom.identify_surface_direction( total_facade_list) QtGui.QApplication.processEvents() self.params.param('Result View').param('Progress').setValue( "Writing the Building Surfaces ... ...") self.progress = 100 py3dmodel.export_collada.write_2_collada( n_list, north_facade_collada_filepath) py3dmodel.export_collada.write_2_collada( s_list, south_facade_collada_filepath) py3dmodel.export_collada.write_2_collada( e_list, east_facade_collada_filepath) py3dmodel.export_collada.write_2_collada( w_list, west_facade_collada_filepath) py3dmodel.export_collada.write_2_collada(total_roof_list, roof_collada_filepath) py3dmodel.export_collada.write_2_collada( total_footprint_list, footprint_collada_filepath) py3dmodel.export_collada.write_2_collada([terrain_shell], terrain_collada_filepath) time2 = time.clock() time = (time2 - time1) / 60.0 time_str = "Total Processing Time: " + str(round(time, 2)) + " mins" QtGui.QApplication.processEvents() self.progress = 100 self.params.param('Result View').param('Progress').setValue( time_str) #if viewer == True: # cmpd = pyliburo.py3dmodel.construct.make_compound(msolid_list) # display_2dlist.append([cmpd]) # display_2dlist.append([terrain_shell]) # pyliburo.py3dmodel.construct.visualise(display_2dlist, ["RED", "WHITE"]) self.timer.stop() except: if self.progress == 10: self.params.param('Result View').param('Progress').setValue( str("there is an error at terrain construction !!!")) if self.progress == 20: self.params.param('Result View').param('Progress').setValue( str("there is an error at building extrusion !!!")) if self.progress == 50: self.params.param('Result View').param('Progress').setValue( str("there is an error at building placement !!!")) if self.progress == 70: self.params.param('Result View').param('Progress').setValue( str("there is an error at building classification !!!")) self.timer.stop()