@@ -28,7 +28,6 @@ def get_timeSeries(day, lon, lat, precision=3600, padding=1800):
28
28
dates ['date' ] = dates ['datetime' ].apply (lambda r : str (r )[:19 ])
29
29
return dates
30
30
31
-
32
31
def cal_sunshine (buildings , day = '2022-01-01' , roof = False ,grids = gpd .GeoDataFrame (), accuracy = 1 , precision = 3600 , padding = 0 ):
33
32
'''
34
33
Calculate the sunshine time in given date.
@@ -48,7 +47,7 @@ def cal_sunshine(buildings, day='2022-01-01', roof=False,grids = gpd.GeoDataFra
48
47
padding : number
49
48
padding time before and after sunrise and sunset
50
49
accuracy : number
51
- size of grids.
50
+ size of grids. Produce vector polygons if set as `vector`
52
51
53
52
**Return**
54
53
@@ -69,12 +68,35 @@ def cal_sunshine(buildings, day='2022-01-01', roof=False,grids = gpd.GeoDataFra
69
68
70
69
# Generate shadow every 1800 s
71
70
shadows = cal_sunshadows (buildings , dates = [day ], precision = precision , padding = padding )
72
- # Grid analysis of shadow cover duration(ground).
73
- grids = cal_shadowcoverage (
74
- shadows , buildings , grids = grids ,roof = roof , precision = precision , accuracy = accuracy )
71
+ if accuracy == 'vector' :
72
+ if roof :
73
+ shadows = shadows [shadows ['type' ] == 'roof' ]
74
+ shadows = bd_preprocess (shadows )
75
+ shadows = shadows .groupby (['date' ,'type' ])['geometry' ].apply (
76
+ lambda df : MultiPolygon (list (df )).buffer (0 )).reset_index ()
77
+ shadows = bd_preprocess (shadows )
78
+ shadows = count_overlapping_features (shadows )
79
+ else :
80
+ shadows = shadows [shadows ['type' ] == 'ground' ]
81
+ shadows = bd_preprocess (shadows )
82
+ shadows = shadows .groupby (['date' ,'type' ])['geometry' ].apply (
83
+ lambda df : MultiPolygon (list (df )).buffer (0 )).reset_index ()
84
+ shadows = bd_preprocess (shadows )
85
+ shadows = count_overlapping_features (shadows )
86
+
87
+ shadows ['time' ] = shadows ['count' ]* precision
88
+ shadows ['Hour' ] = sunlighthour - shadows ['time' ]/ 3600
89
+ shadows .loc [shadows ['Hour' ]<= 0 ,'Hour' ]= 0
90
+ return shadows
91
+ else :
92
+ # Grid analysis of shadow cover duration(ground).
93
+ grids = cal_shadowcoverage (
94
+ shadows , buildings , grids = grids ,roof = roof , precision = precision , accuracy = accuracy )
75
95
76
- grids ['Hour' ] = sunlighthour - grids ['time' ]/ 3600
77
- return grids
96
+ grids ['Hour' ] = sunlighthour - grids ['time' ]/ 3600
97
+ return grids
98
+
99
+
78
100
79
101
80
102
def cal_sunshadows (buildings , cityname = 'somecity' , dates = ['2022-01-01' ], precision = 3600 , padding = 0 ,
@@ -195,4 +217,17 @@ def cal_shadowcoverage(shadows_input, buildings, grids = gpd.GeoDataFrame(),roof
195
217
grids = pd .merge (grids , gridcount , how = 'left' )
196
218
grids ['time' ] = grids ['count' ].fillna (0 )* precision
197
219
198
- return grids
220
+ return grids
221
+
222
+ def count_overlapping_features (gdf ):
223
+ import shapely
224
+ bounds = gdf .geometry .exterior .unary_union
225
+ new_polys = list (shapely .ops .polygonize (bounds ))
226
+ new_gdf = gpd .GeoDataFrame (geometry = new_polys )
227
+ new_gdf ['id' ] = range (len (new_gdf ))
228
+ new_gdf_centroid = new_gdf .copy ()
229
+ new_gdf_centroid ['geometry' ] = new_gdf .centroid
230
+ overlapcount = gpd .sjoin (new_gdf_centroid ,gdf )
231
+ overlapcount = overlapcount .groupby (['id' ])['index_right' ].count ().rename ('count' ).reset_index ()
232
+ out_gdf = pd .merge (new_gdf ,overlapcount )
233
+ return out_gdf
0 commit comments