diff --git a/docs/source/bdshadow.rst b/docs/source/bdshadow.rst index 94432ad..e405419 100644 --- a/docs/source/bdshadow.rst +++ b/docs/source/bdshadow.rst @@ -9,7 +9,7 @@ Building shadow Shadow from sunlight -------------------------------------- -.. function:: pybdshadow.bdshadow_sunlight(buildings, date, merge=False, height='height', ground=0) +.. function:: pybdshadow.bdshadow_sunlight(buildings, date, height='height', roof=False,include_building = True,ground=0) Calculate the sunlight shadow of the buildings. @@ -19,10 +19,12 @@ buildings : GeoDataFrame Buildings. coordinate system should be WGS84 date : datetime Datetime -merge : bool - whether to merge the wall shadows into the building shadows height : string Column name of building height +roof : bool + whether to calculate the roof shadows +include_building : bool + whether the shadow include building outline ground : number Height of the ground diff --git a/docs/source/conf.py b/docs/source/conf.py index 8d8ead8..1a884b8 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -22,8 +22,8 @@ author = 'Qing Yu' # The full version, including alpha/beta/rc tags -release = '0.2.2' -version = '0.2.2' +release = '0.2.3' +version = '0.2.3' html_logo = "_static/logo-wordmark-light.png" html_favicon = '_static/logo.ico' # -- General configuration --------------------------------------------------- diff --git a/example/example-roof.ipynb b/example/example-roof.ipynb new file mode 100644 index 0000000..6296fd1 --- /dev/null +++ b/example/example-roof.ipynb @@ -0,0 +1,103 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import geopandas as gpd\n", + "import pybdshadow\n", + "\n", + "#Read building data\n", + "buildings = gpd.read_file(r'../example/data/bd_demo.json')\n", + "buildings = pybdshadow.bd_preprocess(buildings)\n", + "\n", + "buildings = buildings[(buildings['x']>139.698311)&\n", + "(buildings['x']<139.699311)&\n", + "(buildings['y']>35.533816)&\n", + "(buildings['y']<35.534816)]\n", + "\n", + "#Given UTC time\n", + "date = pd.to_datetime('2015-01-01 03:45:33.959797119')" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "#Calculate shadows\n", + "shadows = pybdshadow.bdshadow_sunlight(buildings,date,roof=True,include_building = False)\n", + "shadows['type'] += ' shadow'" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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9xxvfOMbiy7f19dHa2srPT091NfXM2/evDHdj4qiz33uc0ydOpW/+qu/GrXsd77zHVpaWvjqV786rnM98sgj3Hrrrdx3332jFy7ScH9DM9uQm4s+VKJXjBERKZeXXnqJbdu2MTBwtEPqueeeY8mSJbzhDW8YYc+J6+/vp6ZGH9+loLVDRUTG6KWXXmLLli3HBECAgYEBtmzZwksvvTTuY3/+85/ntNNO46KLLuI973kPt96aXTfkkksu4S/+4i9YvXo1//iP/8gvfvELVq1axfLly/ngBz9IT08PkF0pa+/e7BokLS0tXHLJJUC2hffBD36QSy65hCVLlvCVr3xl8Jy33HILp556KhdddBEvvPDCsPX693//d5YtW8aKFSu4+OKLB7e//vrrXH755SxdupRPfepTg9s/+tGPsnr1as4880w++9nPDm7/2c9+xumnn87ZZ5/ND3/4w8Ht+/bt4x3veAdnnXUWF1xwAU899RQAy5cv58CBA7g7TU1NfPe73wXg2muv5aGHHhr37zlHQVBEZAz6+vrYtm3biGW2bdtGf3//mI+9fv167r33XjZt2sQDDzxw3LKPvb29tLS0cMMNN/D+97+fu+66i6effpr+/n7++Z//edTjP//88zz44IM88cQT/M3f/A19fX1s2LCBO++8k40bN3L//fezfv36Yfe9+eabefDBB9m0aRPr1h0dG7lx48bBetx111289lp2Ovctt9xCS0sLTz31FL/61a946qmn6O7u5s/+7M/46U9/yoYNG9i9e/fgcT772c+yatUqnnrqKf7u7/6Oa6+9FoALL7yQ3/zmN2zevJklS5bw2GOPAfDb3/6W3//93x/bL3gYCoIiImPQ2tp6XAtwqIGBgWM+4Iv1m9/8hrVr19LQ0MC0adN4+9vffszr7373uwF44YUXWLx4MaeeeioA1113HY8++uiox7/yyiupr69n9uzZzJ07l9bWVh577DHe+c53MnnyZKZPn85VV1017L4XXngh73//+/nGN75xzPW/+c1vZsaMGTQ0NHDGGWfwyivZZTrvvvtuzj77bFatWsXmzZt59tlnef7551m8eDFLly7FzHjve987eJxf//rXvO997wPg0ksvpb29nY6ODtasWcOjjz7Ko48+ykc/+lGefvppdu7cycyZM5kyZcoYfrvDUxAUERmDXLdjqcqNRTEf+jU1NWQyGYDjpgvU19cPPq6urh5Ta/XrX/86f/u3f8trr73GOeecQ3t7e8Fjvvzyy9x666384he/4KmnnuLKK68c9wIEF198MY899hiPPfYYl1xyCXPmzOGee+5hzZo14zreUAqCIiJjkP+hX4py+S688EJ++tOf0t3dTWdnZ8FRk6eddhrbt29n69atAHzve9/jTW96E5C9J7hhwwYA7r333lHPefHFF/PjH/+YI0eOcOjQIX76058OW+6ll17i/PPP5+abb2bOnDmD3Z7D6ejoYMqUKcyYMYPW1lYeeOABAE4//XS2b98+eM/03/7t3wb3WbNmDd///veB7KjR2bNnM336dBYtWsTevXvZsmULS5Ys4aKLLuLWW2895r7kRCgIioiMwbx586iurh6xTHV1Nc3NzWM+9rnnnstVV13FWWedxRVXXMHy5cuZMWPGceUaGhr49re/zbve9S6WL19OVVUVH/nIR4DsvbVPfOITrF69etR6Apx99tm8+93vZsWKFVxxxRWce+65w5b75Cc/yfLly1m2bBm///u/z4oVKwoec8WKFaxatYrTTz+dP/mTP+HCCy8crPftt9/OlVdeydlnn83cuXMH9/nc5z7Hhg0bOOuss7jxxhu54447Bl87//zzB7t+16xZw86dO7noootGvbZiaJ6giEig2HmCudGhhSxdunTc0yQ6OzuZOnUqXV1dXHzxxdx+++2cffbZ4zpWGmmeoIhImeUC3NB5gtXV1ROeJ3j99dfz7LPP0t3dzXXXXacAWGYKgiIi4/CGN7yBk046id27dw+uGNPc3DzhSew/+MEPSlRDKYaCoIjIONXU1LBw4cKwqyEToIExIiKSWgqCIiKSWgqCIiKSWgqCIjImmUxm1GXD0iLT1UX3o4/S9ZN1dD/6KJmurrCrxCc/+UnOPPNMPvnJT45a9pFHHuFtb3vbuM+1fft2li1bNu79o0ADY0SETCZDb2/v4E9PTw89PT2Dj/P/39vbS01NDcuWLRvXhPCk6Fr3U47c9x+Qtzza4X/9AZPediWTr3r7CHsWx91xd6qqxtZWuf3229m3b19RE+VFLUGRxMpkMnR3d9PR0UFbWxs7d+5k27ZtPP/882zatIn169fz61//mocffpif//znPPLII/zXf/0XLS0tPP3007z44ots376dXbt20d7eTmdnJ729vUA2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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "#Visualize buildings and shadows using matplotlib\n", + "import matplotlib.pyplot as plt\n", + "fig = plt.figure(1,(10,10))\n", + "ax = plt.subplot(111)\n", + "\n", + "\n", + "#建筑物\n", + "buildings.plot(ax = ax)\n", + "\n", + "#地面阴影\n", + "\n", + "shadows.plot(ax = ax,alpha = 0.7,\n", + "column = 'type', \n", + "categorical=True, \n", + "cmap='Set1_r', \n", + "legend=True)\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "40d3a090f54c6569ab1632332b64b2c03c39dcf918b08424e98f38b5ae0af88f" + }, + "kernelspec": { + "display_name": "Python 3.8.8 ('base')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/setup.py b/setup.py index fa49f03..33b8eb8 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="pybdshadow", - version="0.2.2", + version="0.2.3", author="Qing Yu", author_email="qingyu0815@foxmail.com", description="Python package to generate building shadow geometry", diff --git a/src/pybdshadow/__init__.py b/src/pybdshadow/__init__.py index ced2b53..002fec4 100644 --- a/src/pybdshadow/__init__.py +++ b/src/pybdshadow/__init__.py @@ -32,7 +32,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ -__version__ = '0.2.2' +__version__ = '0.2.3' __author__ = 'Qing Yu ' # module level doc-string diff --git a/src/pybdshadow/preprocess.py b/src/pybdshadow/preprocess.py index 0800394..acbfac4 100644 --- a/src/pybdshadow/preprocess.py +++ b/src/pybdshadow/preprocess.py @@ -71,3 +71,55 @@ def bd_preprocess(buildings, height='height'): allbds = pd.concat(allbds) allbds['building_id'] = range(len(allbds)) return allbds + +def gdf_difference(gdf_a,gdf_b,col = 'building_id'): + ''' + difference gdf_b from gdf_a + ''' + gdfa = gdf_a.copy() + gdfb = gdf_b.copy() + gdfb = gdfb[['geometry']] + #判断重叠 + from shapely.geometry import MultiPolygon + gdfa.crs = gdfb.crs + gdfb = gpd.sjoin(gdfb,gdfa).groupby([col])['geometry'].apply( + lambda df: MultiPolygon(list(df)).buffer(0)).reset_index() + #分割有重叠和无重叠的 + gdfb['tmp'] = 1 + gdfa_1 = pd.merge(gdfa,gdfb[[col,'tmp']],how = 'left') + gdfa = gdfa_1[gdfa_1['tmp'] == 1].drop('tmp',axis = 1) + gdfa_notintersected = gdfa_1[gdfa_1['tmp'].isnull()].drop('tmp',axis = 1) + #对有重叠的进行裁剪 + gdfa = gdfa.sort_values(by = col).set_index(col) + gdfb = gdfb.sort_values(by = col).set_index(col) + gdfa.crs = gdfb.crs + gdfa['geometry'] = gdfa.difference(gdfb) + gdfa = gdfa.reset_index() + #拼合 + gdfa = pd.concat([gdfa,gdfa_notintersected]) + return gdfa + +def gdf_intersect(gdf_a,gdf_b,col = 'building_id'): + ''' + intersect gdf_b from gdf_a + ''' + gdfa = gdf_a.copy() + gdfb = gdf_b.copy() + gdfb = gdfb[['geometry']] + #判断重叠 + from shapely.geometry import MultiPolygon + gdfa.crs = gdfb.crs + gdfb = gpd.sjoin(gdfb,gdfa).groupby([col])['geometry'].apply( + lambda df: MultiPolygon(list(df)).buffer(0)).reset_index() + #分割有重叠和无重叠的 + gdfb['tmp'] = 1 + gdfa_1 = pd.merge(gdfa,gdfb[[col,'tmp']],how = 'left') + gdfa = gdfa_1[gdfa_1['tmp'] == 1].drop('tmp',axis = 1) + #对有重叠的进行裁剪 + gdfa = gdfa.sort_values(by = col).set_index(col) + gdfb = gdfb.sort_values(by = col).set_index(col) + gdfa.crs = gdfb.crs + gdfa['geometry'] = gdfa.intersection(gdfb) + gdfa = gdfa.reset_index() + + return gdfa \ No newline at end of file diff --git a/src/pybdshadow/pybdshadow.py b/src/pybdshadow/pybdshadow.py index 8e6b2d7..bbb3039 100644 --- a/src/pybdshadow/pybdshadow.py +++ b/src/pybdshadow/pybdshadow.py @@ -39,6 +39,7 @@ lonlat_mercator_vector, mercator_lonlat_vector ) +from .preprocess import gdf_difference,gdf_intersect def calSunShadow_vector(shape, shapeHeight, sunPosition): @@ -76,23 +77,27 @@ def calSunShadow_vector(shape, shapeHeight, sunPosition): return shadowShape -def bdshadow_sunlight(buildings, date, merge=True, height='height', ground=0): +def bdshadow_sunlight(buildings, date, height='height', roof=False,include_building = True,ground=0): ''' Calculate the sunlight shadow of the buildings. **Parameters** + buildings : GeoDataFrame Buildings. coordinate system should be WGS84 date : datetime Datetime - merge : bool - whether to merge the wall shadows into the building shadows height : string Column name of building height + roof : bool + whether to calculate the roof shadows + include_building : bool + whether the shadow include building outline ground : number Height of the ground **Return** + shadows : GeoDataFrame Building shadow ''' @@ -126,21 +131,99 @@ def bdshadow_sunlight(buildings, date, merge=True, height='height', ground=0): walls = walls[['x1', 'y1', 'x2', 'y2', 'building_id', 'height']] walls['wall'] = walls.apply(lambda r: [[r['x1'], r['y1']], [r['x2'], r['y2']]], axis=1) - walls_shape = np.array(list(walls['wall'])) + + ground_shadow = walls.copy() + walls_shape = np.array(list(ground_shadow['wall'])) # calculate shadow for walls shadowShape = calSunShadow_vector( - walls_shape, walls['height'].values, sunPosition) - - walls['geometry'] = list(shadowShape) - walls['geometry'] = walls['geometry'].apply(lambda r: Polygon(r)) - walls = gpd.GeoDataFrame(walls) - walls = pd.concat([walls, building]) - if merge: - walls = walls.groupby(['building_id'])['geometry'].apply( - lambda df: MultiPolygon(list(df)).buffer(0)).reset_index() - - return walls + walls_shape, ground_shadow['height'].values, sunPosition) + + ground_shadow['geometry'] = list(shadowShape) + ground_shadow['geometry'] = ground_shadow['geometry'].apply( + lambda r: Polygon(r)) + ground_shadow = gpd.GeoDataFrame(ground_shadow) + + + + ground_shadow = pd.concat([ground_shadow, building]) + ground_shadow = ground_shadow.groupby(['building_id'])['geometry'].apply( + lambda df: MultiPolygon(list(df)).buffer(0)).reset_index() + + ground_shadow['height'] = 0 + ground_shadow['type'] = 'ground' + + if not roof: + if not include_building: + #从地面阴影裁剪建筑轮廓 + ground_shadow = gdf_difference(ground_shadow,buildings) + return ground_shadow + else: + def calwall_shadow(walldata, building): + walls = walldata.copy() + walls_shape = np.array(list(walls['wall'])) + # calculate shadow for walls + shadowShape = calSunShadow_vector( + walls_shape, walls['height'].values, sunPosition) + walls['geometry'] = list(shadowShape) + walls['geometry'] = walls['geometry'].apply(lambda r: Polygon(r)) + walls = gpd.GeoDataFrame(walls) + walls = pd.concat([walls, building]) + + walls = walls.groupby(['building_id'])['geometry'].apply( + lambda df: MultiPolygon(list(df)).buffer(0)).reset_index() + return walls + + # 计算屋顶阴影 + roof_shadows = [] + for roof_height in walls[height].drop_duplicates(): + # 高于给定高度的墙 + walls_high = walls[walls[height] > roof_height].copy() + if len(walls_high) == 0: + continue + walls_high[height] -= roof_height + # 高于给定高度的建筑 + building_high = building[building[height] > roof_height].copy() + if len(building_high) == 0: + continue + building_high[height] -= roof_height + # 所有建筑在此高度的阴影 + building_shadow_height = calwall_shadow(walls_high, building_high) + # 在此高度的建筑屋顶 + building_roof = building[building[height] == roof_height].copy() + building_shadow_height.crs = building_roof.crs + # 取有遮挡的阴影 + building_shadow_height = gpd.sjoin( + building_shadow_height, building_roof) + if len(building_shadow_height) == 0: + continue + # 与屋顶做交集 + building_roof = gdf_intersect(building_roof,building_shadow_height) + + # 再减去这个高度以上的建筑 + building_higher = building[building[height] > roof_height].copy() + building_roof = gdf_difference(building_roof,building_higher) + + #给出高度信息 + building_roof['height'] = roof_height + building_roof = building_roof[-building_roof['geometry'].is_empty] + + roof_shadows.append(building_roof) + if len(roof_shadows) == 0: + roof_shadow = gpd.GeoDataFrame() + else: + roof_shadow = pd.concat(roof_shadows)[ + ['height', 'building_id', 'geometry']] + roof_shadow['type'] = 'roof' + + if not include_building: + #从地面阴影裁剪建筑轮廓 + ground_shadow = gdf_difference(ground_shadow,buildings) + + shadows = pd.concat([roof_shadow, ground_shadow]) + shadows.crs = None + shadows['geometry'] = shadows.buffer(0.000001).buffer(-0.000001) + return shadows def calPointLightShadow_vector(shape, shapeHeight, pointLight): @@ -183,6 +266,7 @@ def bdshadow_pointlight(buildings, Calculate the sunlight shadow of the buildings. **Parameters** + buildings : GeoDataFrame Buildings. coordinate system should be WGS84 pointlon,pointlat,pointheight : float @@ -197,6 +281,7 @@ def bdshadow_pointlight(buildings, Height of the ground **Return** + shadows : GeoDataFrame Building shadow ''' diff --git a/src/pybdshadow/tests/test_pybdshadow.py b/src/pybdshadow/tests/test_pybdshadow.py index 4076648..2480a14 100644 --- a/src/pybdshadow/tests/test_pybdshadow.py +++ b/src/pybdshadow/tests/test_pybdshadow.py @@ -7,43 +7,49 @@ class Testpybdshadow: def test_bdshadow_sunlight(self): + buildings = gpd.GeoDataFrame({ - 'height': [42], + 'height': [42, 9], 'geometry': [ Polygon([(139.698311, 35.533796), - (139.698311, - 35.533642), - (139.699075, - 35.533637), - (139.699079, - 35.53417), - (139.698891, - 35.53417), - (139.698888, - 35.533794), - (139.698311, 35.533796)])]}) - date = pd.to_datetime('2015-01-01 02:45:33.959797119') + (139.698311, + 35.533642), + (139.699075, + 35.533637), + (139.699079, + 35.53417), + (139.698891, + 35.53417), + (139.698888, + 35.533794), + (139.698311, 35.533796)]), + Polygon([(139.69799, 35.534175), + (139.697988, 35.53389), + (139.698814, 35.533885), + (139.698816, 35.534171), + (139.69799, 35.534175)])]}) + date = pd.to_datetime('2015-01-01 03:45:33.959797119') buildings = pybdshadow.bd_preprocess(buildings) buildingshadow = pybdshadow.bdshadow_sunlight( - buildings, date, merge=True) + buildings, date, roof=True, include_building=False) area = buildingshadow['geometry'].iloc[0] area = np.array(area.exterior.coords) - truth = np.array([[139.698311, 35.533796], - [139.69831102, 35.533796], - [139.69831102, 35.533796], - [139.69831239, 35.53429879], - [139.69888939, 35.53429679], - [139.69889239, 35.53467279], - [139.69908039, 35.53467279], - [139.69907902, 35.53417], - [139.69907502, 35.533637], - [139.699075, 35.533637], - [139.699075, 35.533637], - [139.698311, 35.533642], - [139.698311, 35.533796]]) + truth = np.array([(139.6983434498457, 35.53388784954066), + (139.698343456533, 35.533887872006716), + (139.6984440527688, 35.53417277873741), + (139.69844406145836, 35.534172800060766), + (139.69844408446318, 35.534172801043766), + (139.69881597541797, 35.534171000119045), + (139.69881599883948, 35.53417099885312), + (139.6988159998281, 35.53417097541834), + (139.69881400017155, 35.533885024533475), + (139.6988139988598, 35.53388500115515), + (139.69881397546646, 35.53388500014851), + (139.69834347324914, 35.53388784822488), + (139.6983434498457, 35.53388784954066)]) assert np.allclose(area, truth) pybdshadow.show_bdshadow(buildings=buildings, diff --git a/src/test.ipynb b/src/test.ipynb new file mode 100644 index 0000000..e0bb442 --- /dev/null +++ b/src/test.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import geopandas as gpd\n", + "import pybdshadow\n", + "\n", + "#Read building data\n", + "buildings = gpd.read_file(r'../example/data/bd_demo.json')\n", + "buildings = pybdshadow.bd_preprocess(buildings)\n", + "\n", + "buildings = buildings[(buildings['x']>139.698311)&\n", + "(buildings['x']<139.699311)&\n", + "(buildings['y']>35.533816)&\n", + "(buildings['y']<35.534816)]\n", + "\n", + "#Given UTC time\n", + "date = pd.to_datetime('2015-01-01 03:45:33.959797119')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "#Calculate shadows\n", + "shadows = pybdshadow.bdshadow_sunlight(buildings,date,roof=True,include_building = False)\n", + "shadows['type'] += ' shadow'" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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9xxvfOMbiy7f19dHa2srPT091NfXM2/evDHdj4qiz33uc0ydOpW/+qu/GrXsd77zHVpaWvjqV786rnM98sgj3Hrrrdx3332jFy7ScH9DM9uQm4s+VKJXjBERKZeXXnqJbdu2MTBwtEPqueeeY8mSJbzhDW8YYc+J6+/vp6ZGH9+loLVDRUTG6KWXXmLLli3HBECAgYEBtmzZwksvvTTuY3/+85/ntNNO46KLLuI973kPt96aXTfkkksu4S/+4i9YvXo1//iP/8gvfvELVq1axfLly/ngBz9IT08PkF0pa+/e7BokLS0tXHLJJUC2hffBD36QSy65hCVLlvCVr3xl8Jy33HILp556KhdddBEvvPDCsPX693//d5YtW8aKFSu4+OKLB7e//vrrXH755SxdupRPfepTg9s/+tGPsnr1as4880w++9nPDm7/2c9+xumnn87ZZ5/ND3/4w8Ht+/bt4x3veAdnnXUWF1xwAU899RQAy5cv58CBA7g7TU1NfPe73wXg2muv5aGHHhr37zlHQVBEZAz6+vrYtm3biGW2bdtGf3//mI+9fv167r33XjZt2sQDDzxw3LKPvb29tLS0cMMNN/D+97+fu+66i6effpr+/n7++Z//edTjP//88zz44IM88cQT/M3f/A19fX1s2LCBO++8k40bN3L//fezfv36Yfe9+eabefDBB9m0aRPr1h0dG7lx48bBetx111289lp2Ovctt9xCS0sLTz31FL/61a946qmn6O7u5s/+7M/46U9/yoYNG9i9e/fgcT772c+yatUqnnrqKf7u7/6Oa6+9FoALL7yQ3/zmN2zevJklS5bw2GOPAfDb3/6W3//93x/bL3gYCoIiImPQ2tp6XAtwqIGBgWM+4Iv1m9/8hrVr19LQ0MC0adN4+9vffszr7373uwF44YUXWLx4MaeeeioA1113HY8++uiox7/yyiupr69n9uzZzJ07l9bWVh577DHe+c53MnnyZKZPn85VV1017L4XXngh73//+/nGN75xzPW/+c1vZsaMGTQ0NHDGGWfwyivZZTrvvvtuzj77bFatWsXmzZt59tlnef7551m8eDFLly7FzHjve987eJxf//rXvO997wPg0ksvpb29nY6ODtasWcOjjz7Ko48+ykc/+lGefvppdu7cycyZM5kyZcoYfrvDUxAUERmDXLdjqcqNRTEf+jU1NWQyGYDjpgvU19cPPq6urh5Ta/XrX/86f/u3f8trr73GOeecQ3t7e8Fjvvzyy9x666384he/4KmnnuLKK68c9wIEF198MY899hiPPfYYl1xyCXPmzOGee+5hzZo14zreUAqCIiJjkP+hX4py+S688EJ++tOf0t3dTWdnZ8FRk6eddhrbt29n69atAHzve9/jTW96E5C9J7hhwwYA7r333lHPefHFF/PjH/+YI0eOcOjQIX76058OW+6ll17i/PPP5+abb2bOnDmD3Z7D6ejoYMqUKcyYMYPW1lYeeOABAE4//XS2b98+eM/03/7t3wb3WbNmDd///veB7KjR2bNnM336dBYtWsTevXvZsmULS5Ys4aKLLuLWW2895r7kRCgIioiMwbx586iurh6xTHV1Nc3NzWM+9rnnnstVV13FWWedxRVXXMHy5cuZMWPGceUaGhr49re/zbve9S6WL19OVVUVH/nIR4DsvbVPfOITrF69etR6Apx99tm8+93vZsWKFVxxxRWce+65w5b75Cc/yfLly1m2bBm///u/z4oVKwoec8WKFaxatYrTTz+dP/mTP+HCCy8crPftt9/OlVdeydlnn83cuXMH9/nc5z7Hhg0bOOuss7jxxhu54447Bl87//zzB7t+16xZw86dO7noootGvbZiaJ6giEig2HmCudGhhSxdunTc0yQ6OzuZOnUqXV1dXHzxxdx+++2cffbZ4zpWGmmeoIhImeUC3NB5gtXV1ROeJ3j99dfz7LPP0t3dzXXXXacAWGYKgiIi4/CGN7yBk046id27dw+uGNPc3DzhSew/+MEPSlRDKYaCoIjIONXU1LBw4cKwqyEToIExIiKSWgqCIiKSWgqCIiKSWgqCIjImmUxm1GXD0iLT1UX3o4/S9ZN1dD/6KJmurrCrxCc/+UnOPPNMPvnJT45a9pFHHuFtb3vbuM+1fft2li1bNu79o0ADY0SETCZDb2/v4E9PTw89PT2Dj/P/39vbS01NDcuWLRvXhPCk6Fr3U47c9x+Qtzza4X/9AZPediWTr3r7CHsWx91xd6qqxtZWuf3229m3b19RE+VFLUGRxMpkMnR3d9PR0UFbWxs7d+5k27ZtPP/882zatIn169fz61//mocffpif//znPPLII/zXf/0XLS0tPP3007z44ots376dXbt20d7eTmdnJ729vUA2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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "#Visualize buildings and shadows using matplotlib\n", + "import matplotlib.pyplot as plt\n", + "fig = plt.figure(1,(10,10))\n", + "ax = plt.subplot(111)\n", + "\n", + "\n", + "#建筑物\n", + "buildings.plot(ax = ax)\n", + "\n", + "#地面阴影\n", + "\n", + "shadows.plot(ax = ax,\n", + " alpha = 0.7,\n", + " column = 'type', \n", + " categorical=True, \n", + " cmap='Set1_r', \n", + " legend=True)\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "40d3a090f54c6569ab1632332b64b2c03c39dcf918b08424e98f38b5ae0af88f" + }, + "kernelspec": { + "display_name": "Python 3.8.8 ('base')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}