Skip to content

Commit

Permalink
Merge pull request #21 from ni1o1/0.3.5
Browse files Browse the repository at this point in the history
0.3.5
  • Loading branch information
ni1o1 authored Jan 3, 2024
2 parents 070cf36 + ffd85ea commit afcc53c
Show file tree
Hide file tree
Showing 12 changed files with 1,397 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.7", "3.8", "3.9"]
python-version: ["3.8", "3.9"]

steps:
- uses: actions/checkout@v2
Expand Down
174 changes: 174 additions & 0 deletions example/Example2-facade shadow.ipynb

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ suncalc
keplergl
scikit-opt
transbigdata
mapbox_vector_tile
vt2geojson
requests
tqdm
retrying
7 changes: 3 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="pybdshadow",
version="0.3.4",
version="0.3.5",
author="Qing Yu",
author_email="qingyu0815@foxmail.com",
description="Python package to generate building shadow geometry",
Expand All @@ -17,7 +17,7 @@
"Bug Tracker": "https://github.com/ni1o1/pybdshadow/issues",
},
install_requires=[
"numpy", "pandas", "shapely", "geopandas", "matplotlib","suncalc","keplergl","transbigdata"
"numpy", "pandas", "shapely", "geopandas", "matplotlib","suncalc","keplergl","transbigdata","mapbox_vector_tile","vt2geojson","requests","tqdm","retrying"
],
classifiers=[
"Operating System :: OS Independent",
Expand All @@ -26,11 +26,10 @@
"Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
],
package_dir={'pybdshadow': 'src/pybdshadow'},
packages=['pybdshadow'],
python_requires=">=3.6",
python_requires=">=3.8",
)
22 changes: 20 additions & 2 deletions src/pybdshadow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""

__version__ = '0.3.4'
__version__ = '0.3.5'
__author__ = 'Qing Yu <qingyu0815@foxmail.com>'

# module level doc-string
__doc__ = """
`pybdshadow` - Python package to generate building shadow geometry.
"""
from .pybdshadow import *
from .get_buildings import (
get_buildings_by_polygon,
get_buildings_by_bounds,
)
from .pybdshadow import (
bdshadow_sunlight,
bdshadow_pointlight
Expand All @@ -49,6 +53,7 @@
)
from .visualization import (
show_bdshadow,
show_sunshine,
)
from .analysis import (
cal_sunshine,
Expand All @@ -57,12 +62,25 @@
get_timetable
)

from .facade import (
cal_sunshine_facade
)

from .utils import (
extrude_poly
)

__all__ = ['bdshadow_sunlight',
'bdshadow_pointlight',
'bd_preprocess',
'show_bdshadow',
'cal_sunshine',
'cal_sunshadows',
'cal_shadowcoverage',
'get_timetable'
'get_timetable',
'get_buildings_by_polygon',
'get_buildings_by_bounds',
'cal_sunshine_facade',
'show_sunshine',
'extrude_poly'
]
63 changes: 38 additions & 25 deletions src/pybdshadow/analysis.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import pandas as pd
from suncalc import get_times
from shapely.geometry import MultiPolygon
from shapely.geometry import MultiPolygon,Polygon
import transbigdata as tbd
import geopandas as gpd
from .pybdshadow import (
bdshadow_sunlight,
)
from .preprocess import bd_preprocess

from .utils import count_overlapping_features

def get_timetable(lon, lat, dates=['2022-01-01'], precision=3600, padding=1800):
# generate timetable with given interval
Expand Down Expand Up @@ -56,6 +56,8 @@ def cal_sunshine(buildings, day='2022-01-01', roof=False, grids=gpd.GeoDataFrame
grids generated by TransBigData in study area, each grids have a `time` column store the sunshine time
'''


# calculate day time duration
lon, lat = buildings['geometry'].iloc[0].bounds[:2]
date = pd.to_datetime(day+' 12:45:33.959797119')
Expand All @@ -73,22 +75,47 @@ def cal_sunshine(buildings, day='2022-01-01', roof=False, grids=gpd.GeoDataFrame
if accuracy == 'vector':
if roof:
shadows = shadows[shadows['type'] == 'roof']
shadows = bd_preprocess(shadows)
shadows = shadows.groupby(['date', 'type'])['geometry'].apply(
lambda df: MultiPolygon(list(df)).buffer(0)).reset_index()
shadows = bd_preprocess(shadows)
shadows = count_overlapping_features(shadows)
if len(shadows)>0:
shadows = bd_preprocess(shadows)
shadows = shadows.groupby(['date', 'type','height'])['geometry'].apply(
lambda df: MultiPolygon(list(df)).buffer(0)).reset_index()
shadows = bd_preprocess(shadows)

# 额外:增加屋顶面
shadows = pd.concat([shadows, buildings])
#return shadows
shadows = shadows.groupby('height').apply(count_overlapping_features).reset_index()
shadows['count'] -= 1
else:
shadows = shadows[shadows['type'] == 'ground']

shadows = bd_preprocess(shadows)
shadows = shadows.groupby(['date', 'type'])['geometry'].apply(
lambda df: MultiPolygon(list(df)).buffer(0)).reset_index()
lambda df: MultiPolygon(list(df)).buffer(0)).reset_index()
shadows = bd_preprocess(shadows)
shadows = count_overlapping_features(shadows)

# 额外:增加地面面
minpos = shadows.bounds[['minx','miny']].min()
maxpos = shadows.bounds[['maxx','maxy']].max()

ground = gpd.GeoDataFrame(geometry=[
Polygon([
[minpos['minx'],minpos['miny']],
[minpos['minx'],maxpos['maxy']],
[maxpos['maxx'],maxpos['maxy']],
[maxpos['maxx'],minpos['miny']],
])
])
shadows = pd.concat([shadows,
ground
])
shadows = count_overlapping_features(shadows,buffer=False)
shadows['count'] -= 1


shadows['time'] = shadows['count']*precision
shadows['Hour'] = sunlighthour-shadows['time']/3600
shadows.loc[shadows['Hour'] <= 0, 'Hour'] = 0
#shadows.loc[shadows['Hour'] <= 0, 'Hour'] = 0
return shadows
else:
# Grid analysis of shadow cover duration(ground).
Expand All @@ -97,7 +124,7 @@ def cal_sunshine(buildings, day='2022-01-01', roof=False, grids=gpd.GeoDataFrame

grids['Hour'] = sunlighthour-grids['time']/3600
return grids


def cal_sunshadows(buildings, cityname='somecity', dates=['2022-01-01'], precision=3600, padding=1800,
roof=True, include_building=True, save_shadows=False, printlog=False):
Expand Down Expand Up @@ -222,17 +249,3 @@ def cal_shadowcoverage(shadows_input, buildings, grids=gpd.GeoDataFrame(), roof=

return grids


def count_overlapping_features(gdf):
import shapely
bounds = gdf.geometry.exterior.unary_union
new_polys = list(shapely.ops.polygonize(bounds))
new_gdf = gpd.GeoDataFrame(geometry=new_polys)
new_gdf['id'] = range(len(new_gdf))
new_gdf_centroid = new_gdf.copy()
new_gdf_centroid['geometry'] = new_gdf.centroid
overlapcount = gpd.sjoin(new_gdf_centroid, gdf)
overlapcount = overlapcount.groupby(
['id'])['index_right'].count().rename('count').reset_index()
out_gdf = pd.merge(new_gdf, overlapcount)
return out_gdf
Loading

0 comments on commit afcc53c

Please sign in to comment.