def calculate_radiation_single_day(day, in_surface_raster, in_points_feature, T_G_day, latitude, locationtemp1, aspect_slope, heightoffset, path_arcgis_db): # Local Variables Latitude = str(latitude) skySize = '1400' # max 10000 dayInterval = '1' hourInterval = '1' calcDirections = '32' zenithDivisions = '600' # max 1200cor hlaf the skysize azimuthDivisions = '80' # max 160 diffuseProp = str(T_G_day.loc[day, 'diff']) transmittivity = str(T_G_day.loc[day, 'trr']) heightoffset = str(heightoffset) global_radiation = locationtemp1 + '\\' + 'Day_' + str(day) + '.shp' timeConfig = 'WithinDay ' + str(day) + ', 0, 24' arcpy.env.workspace = path_arcgis_db arcpy.env.overwriteOutput = True arcpy.CheckOutExtension("spatial") # Run the extension of arcgis, retry max_retries times before giving up... max_retries = 3 for _ in range(max_retries): try: arcpy.sa.PointsSolarRadiation(in_surface_raster, in_points_feature, global_radiation, heightoffset, Latitude, skySize, timeConfig, dayInterval, hourInterval, "INTERVAL", "1", aspect_slope, calcDirections, zenithDivisions, azimuthDivisions, "STANDARD_OVERCAST_SKY", diffuseProp, transmittivity, "#", "#", "#") print('complete calculating radiation of day No. %(day)i' % locals()) return arcpy.GetMessages() except: print(traceback.format_exc()) raise AssertionError('CalcRadiation failed %(max_retries)i times... giving up!' % locals())
def Burn(Buildings, DEM, DEMfinal, locationtemp1, DEM_extent, gv): # Create a raster with all the buildings Outraster = locationtemp1 + '\\' + 'AllRaster' arcpy.env.extent = DEM_extent # These coordinates are extracted from the environment settings/once the DEM raster is selected directly in ArcGIS, arcpy.FeatureToRaster_conversion(Buildings, 'height_ag', Outraster, '0.5') # creating raster of the footprints of the buildings # Clear non values and add all the Buildings to the DEM OutNullRas = arcpy.sa.IsNull(Outraster) # identify noData Locations Output = arcpy.sa.Con(OutNullRas == 1, 0, Outraster) RadiationDEM = arcpy.sa.Raster(DEM) + Output RadiationDEM.save(DEMfinal) gv.log('complete burning buildings into raster') return arcpy.GetMessages()
def burn_buildings_into_raster(simple_context_shp, terrain_tif, dem_rasterfinal_path, temporary_folder, dem_raster_extent): # Create a raster with all the buildings Outraster = temporary_folder + '\\' + 'AllRaster' # These coordinates are extracted from the environment settings/once the DEM raster is selected directly in ArcGIS, arcpy.env.extent = dem_raster_extent # creating raster of the footprints of the buildings arcpy.FeatureToRaster_conversion(simple_context_shp, 'height_ag', Outraster, '0.5') # Clear non values and add all the Buildings to the DEM OutNullRas = arcpy.sa.IsNull(Outraster) # identify noData Locations Output = arcpy.sa.Con(OutNullRas == 1, 0, Outraster) RadiationDEM = arcpy.sa.Raster(terrain_tif) + Output RadiationDEM.save(dem_rasterfinal_path) print('complete burning buildings into raster') return arcpy.GetMessages()
def CalcRadiation(day, in_surface_raster, in_points_feature, T_G_day, latitude, locationtemp1, aspect_slope, heightoffset, gv): # Local Variables Latitude = str(latitude) skySize = '1400' # max 10000 dayInterval = '1' hourInterval = '1' calcDirections = '32' zenithDivisions = '600' # max 1200cor hlaf the skysize azimuthDivisions = '80' # max 160 diffuseProp = str(T_G_day.loc[day, 'diff']) transmittivity = str(T_G_day.loc[day, 'trr']) heightoffset = str(heightoffset) global_radiation = locationtemp1 + '\\' + 'Day_' + str(day) + '.shp' timeConfig = 'WithinDay ' + str(day) + ', 0, 24' # Run the extension of arcgis arcpy.sa.PointsSolarRadiation(in_surface_raster, in_points_feature, global_radiation, heightoffset, Latitude, skySize, timeConfig, dayInterval, hourInterval, "INTERVAL", "1", aspect_slope, calcDirections, zenithDivisions, azimuthDivisions, "STANDARD_OVERCAST_SKY", diffuseProp, transmittivity, "#", "#", "#") gv.log('complete calculating radiation of day No. ' + str(day)) return arcpy.GetMessages()
def CalcBoundaries(Simple_CQ, locationtemp1, locationtemp2, DataFactorsCentroids, DataFactorsBoundaries, gv): # local variables NearTable = locationtemp1 + '\\' + 'NearTable.dbf' CQLines = locationtemp2 + '\\' + '\CQLines' CQVertices = locationtemp2 + '\\' + 'CQVertices' CQSegments = locationtemp2 + '\\' + 'CQSegment' CQSegments_centroid = locationtemp2 + '\\' + 'CQSegmentCentro' centroidsTable_name = 'CentroidCQdata.dbf' centroidsTable = locationtemp1 + '\\' + centroidsTable_name Overlaptable = locationtemp1 + '\\' + 'overlapingTable.csv' # Create points in the centroid of segment line and table with near features: # indentifying for each segment of line of building A the segment of line of building B in common. arcpy.FeatureToLine_management(Simple_CQ, CQLines) arcpy.FeatureVerticesToPoints_management(Simple_CQ, CQVertices, 'ALL') arcpy.SplitLineAtPoint_management(CQLines, CQVertices, CQSegments, '2 METERS') arcpy.FeatureVerticesToPoints_management(CQSegments, CQSegments_centroid, 'MID') arcpy.GenerateNearTable_analysis(CQSegments_centroid, CQSegments_centroid, NearTable, "1 Meters", "NO_LOCATION", "NO_ANGLE", "CLOSEST", "0") # Import the table with NearMatches NearMatches = Dbf5(NearTable).to_dataframe() # Import the table with attributes of the centroids of the Segments arcpy.TableToTable_conversion(CQSegments_centroid, locationtemp1, centroidsTable_name) DataCentroids0 = Dbf5(centroidsTable).to_dataframe() DataCentroids = DataCentroids0[['Name', 'height_ag', 'ORIG_FID']] # CreateJoin to Assign a Factor to every Centroid of the lines, FirstJoin = pd.merge(NearMatches, DataCentroids, left_on='IN_FID', right_on='ORIG_FID') SecondaryJoin = pd.merge(FirstJoin, DataCentroids, left_on='NEAR_FID', right_on='ORIG_FID') # delete matches within the same polygon Name (it can happen that lines are too close one to the other) # also delete matches with a distance of more than 20 cm making room for mistakes during the simplicfication of buildings but avoiding deleten boundaries rows = SecondaryJoin.IN_FID.count() for row in range(rows): if SecondaryJoin.loc[row, 'Name_x'] == SecondaryJoin.loc[row, 'Name_y'] or SecondaryJoin.loc[ row, 'NEAR_DIST'] > 0.2: SecondaryJoin = SecondaryJoin.drop(row) SecondaryJoin.reset_index(inplace=True) # FactorShade = 0 if the line exist in a building totally covered by another one, and Freeheight is equal to the height of the line # that is not obstructed by the other building rows = SecondaryJoin.IN_FID.count() SecondaryJoin['FactorShade'] = 0 SecondaryJoin['Freeheight'] = 0 for row in range(rows): if SecondaryJoin.loc[row, 'height_ag_x'] <= SecondaryJoin.loc[row, 'height_ag_y']: SecondaryJoin.loc[row, 'FactorShade'] = 0 SecondaryJoin.loc[row, 'Freeheight'] = 0 elif SecondaryJoin.loc[row, 'height_ag_x'] > SecondaryJoin.loc[row, 'height_ag_y'] and SecondaryJoin.loc[ row, 'height_ag_x'] - 1 <= SecondaryJoin.loc[row, 'height_ag_y']: SecondaryJoin.loc[row, 'FactorShade'] = 0 else: SecondaryJoin.loc[row, 'FactorShade'] = 1 SecondaryJoin.loc[row, 'Freeheight'] = abs( SecondaryJoin.loc[row, 'height_ag_y'] - SecondaryJoin.loc[row, 'height_ag_x']) # Create and export Secondary Join with results, it will be Useful for the function CalcObservers SecondaryJoin.to_csv(DataFactorsBoundaries, index=False) # Update table Datacentroids with the Fields Freeheight and Factor Shade. for those buildings without # shading boundaries these factors are equal to 1 and the field 'height' respectively. DataCentroids['FactorShade'] = 1 DataCentroids['Freeheight'] = DataCentroids.height_ag Results = DataCentroids.merge(SecondaryJoin, left_on='ORIG_FID', right_on='ORIG_FID_x', how='outer') Results.FactorShade_y.fillna(Results['FactorShade_x'], inplace=True) Results.Freeheight_y.fillna(Results['Freeheight_x'], inplace=True) Results.rename(columns={'FactorShade_y': 'FactorShade', 'Freeheight_y': 'Freeheight'}, inplace=True) FinalDataCentroids = pd.DataFrame(Results, columns={'ORIG_FID', 'height', 'FactorShade', 'Freeheight'}) FinalDataCentroids.to_csv(DataFactorsCentroids, index=False) gv.log('complete calculating boundaries') return arcpy.GetMessages()
def CalcObservers(Simple_CQ, Observers, DataFactorsBoundaries, locationtemporal2, gv): # local variables Buffer_CQ = locationtemporal2 + '\\' + 'BufferCQ' temporal_lines = locationtemporal2 + '\\' + 'lines' Points = locationtemporal2 + '\\' + 'Points' AggregatedBuffer = locationtemporal2 + '\\' + 'BufferAggregated' temporal_lines3 = locationtemporal2 + '\\' + 'lines3' Points3 = locationtemporal2 + '\\' + 'Points3' Points3Updated = locationtemporal2 + '\\' + 'Points3Updated' EraseObservers = locationtemporal2 + '\\' + 'eraseobservers' Observers0 = locationtemporal2 + '\\' + 'observers0' NonoverlappingBuildings = locationtemporal2 + '\\' + 'Non_overlap' templines = locationtemporal2 + '\\' + 'templines' templines2 = locationtemporal2 + '\\' + 'templines2' Buffer_CQ0 = locationtemporal2 + '\\' + 'Buffer_CQ0' Buffer_CQ = locationtemporal2 + '\\' + 'Buffer_CQ' Buffer_CQ1 = locationtemporal2 + '\\' + 'Buffer_CQ1' Simple_CQcopy = locationtemporal2 + '\\' + 'Simple_CQcopy' # First increase the boundaries in 2m of each surface in the community to # analyze- this will avoid that the observers overlap the buildings and Simplify # the community vertices to only create 1 point per surface arcpy.CopyFeatures_management(Simple_CQ, Simple_CQcopy) # Make Square-like buffers arcpy.PolygonToLine_management(Simple_CQcopy, templines, "IGNORE_NEIGHBORS") arcpy.SplitLine_management(templines, templines2) arcpy.Buffer_analysis(templines2, Buffer_CQ0, "0.75 Meters", "FULL", "FLAT", "NONE", "#") arcpy.Append_management(Simple_CQcopy, Buffer_CQ0, "NO_TEST") arcpy.Dissolve_management(Buffer_CQ0, Buffer_CQ1, "Name", "#", "SINGLE_PART", "DISSOLVE_LINES") arcpy.SimplifyBuilding_cartography(Buffer_CQ1, Buffer_CQ, simplification_tolerance=8, minimum_area=None) # arcpy.Buffer_analysis(Simple_CQ,Buffer_CQ,buffer_distance_or_field=1, line_end_type='FLAT') # buffer with a flat finishing # arcpy.Generalize_edit(Buffer_CQ,"2 METERS") # Transform all polygons of the simplified areas to observation points arcpy.SplitLine_management(Buffer_CQ, temporal_lines) arcpy.FeatureVerticesToPoints_management(temporal_lines, Points, 'MID') # Second the transformation of Lines to a mid point # Join all the polygons to get extra vertices, make lines and then get points. # these points should be added to the original observation points arcpy.AggregatePolygons_cartography(Buffer_CQ, AggregatedBuffer, "0.5 Meters", "0 SquareMeters", "0 SquareMeters", "ORTHOGONAL") # agregate polygons arcpy.SplitLine_management(AggregatedBuffer, temporal_lines3) # make lines arcpy.FeatureVerticesToPoints_management(temporal_lines3, Points3, 'MID') # create extra points # add information to Points3 about their buildings arcpy.SpatialJoin_analysis(Points3, Buffer_CQ, Points3Updated, "JOIN_ONE_TO_ONE", "KEEP_ALL", match_option="CLOSEST", search_radius="5 METERS") arcpy.Erase_analysis(Points3Updated, Points, EraseObservers, "2 Meters") # erase overlaping points arcpy.Merge_management([Points, EraseObservers], Observers0) # erase overlaping points # Eliminate Observation points above roofs of the highest surfaces(a trick to make the # Import Overlaptable from function CalcBoundaries containing the data about buildings overlaping, eliminate duplicades, chose only those ones no overlaped and reindex DataNear = pd.read_csv(DataFactorsBoundaries) CleanDataNear = DataNear[DataNear['FactorShade'] == 1] CleanDataNear.drop_duplicates(subset='Name_x', inplace=True) CleanDataNear.reset_index(inplace=True) rows = CleanDataNear.Name_x.count() for row in range(rows): Field = "Name" # select field where the name exists to iterate Value = CleanDataNear.loc[row, 'Name_x'] # set the value or name of the City quarter Where_clausule = '''''' + '"' + Field + '"' + "=" + "\'" + str( Value) + "\'" + '''''' # strange writing to introduce in ArcGIS if row == 0: arcpy.MakeFeatureLayer_management(Simple_CQ, 'Simple_lyr') arcpy.SelectLayerByAttribute_management('Simple_lyr', "NEW_SELECTION", Where_clausule) else: arcpy.SelectLayerByAttribute_management('Simple_lyr', "ADD_TO_SELECTION", Where_clausule) arcpy.CopyFeatures_management('simple_lyr', NonoverlappingBuildings) arcpy.ErasePoint_edit(Observers0, NonoverlappingBuildings, "INSIDE") arcpy.CopyFeatures_management(Observers0, Observers) # copy features to reset the OBJECTID with arcpy.da.UpdateCursor(Observers, ["OBJECTID", "ORIG_FID"]) as cursor: for row in cursor: row[1] = row[0] cursor.updateRow(row) gv.log('complete calculating observers') return arcpy.GetMessages()