Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline exercises for notebooks 1, 2, 3, and 4 #15

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
127 changes: 126 additions & 1 deletion 03-spatial-joins.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,92 @@
"joined['continent'].value_counts()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"**Exercise**: Which rivers pass within 1 degree of Paris? And for Hong Kong?\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would maybe do it in meters (that's often problem that you need to convert the crs for that)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried first but I ran into issues trying to get a world CRS in metres that worked and the rivers layer was acting up so, for the sake of the example, I left it on degrees.

"\n",
"Tip: `rivers` contains empty geometries, make sure to get rid of them before anything else\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!--\n",
"paris = cities.query('name == \"Paris\"')\\\n",
" ['geometry']\\\n",
" .squeeze()\\\n",
" .buffer(1)\n",
"\n",
"river_lines = rivers[rivers.geometry.notna()]\n",
"\n",
"river_lines[river_lines.crosses(paris)]\n",
"\n",
"hk = cities.query('name == \"Hong Kong\"')\\\n",
" ['geometry']\\\n",
" .squeeze()\\\n",
" .buffer(1)\n",
"\n",
"river_lines = rivers[rivers.geometry.notna()]\n",
"\n",
"river_lines[river_lines.crosses(hk)]\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"**Exercise** [PRO]: Find all European cities within 1 degre of at least one river\n",
"\n",
"\n",
"This requires:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. Obtaining a list of European cities\n",
"1. Creating a `GeoDataFrame` with all river lines\n",
"1. For every European city, checking whether at least one river \"crosses\" the area within 1 degree\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this an exercise for notebook 2 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A list of European cities requires a spatial join. It's a compound exercise.

"1. If so, saving the record of a city"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!--\n",
"eu_cities = joined.query('continent == \"Europe\"')\n",
"river_lines = rivers[rivers.geometry.notna()]\n",
"\n",
"answer = []\n",
"for id, city in eu_cities.iterrows():\n",
" buf = city['geometry'].buffer(1)\n",
" rivers_crossing = river_lines.crosses(buf).sum()\n",
" if rivers_crossing > 0:\n",
" answer.append(city)\n",
"answer = geopandas.GeoDataFrame(answer, \n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would personally do it with a function and apply. It is maybe more complex in the end, but a good pattern to show IMO.
Or first with loop, and then as exercise to convert it to apply

" crs=eu_cities.crs)\n",
"answer\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -300,6 +386,45 @@
"\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"**Exercise**: if we define rural as those areas that are not within 50Km of the centre of a city, what is the extention of rural North America? What is the percentage that it covers?\n",
"\n",
"Tip: make sure your projection allows you to calculate distances in metres ([wink wink](http://epsg.io/3083))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!--\n",
"namerica = countries.query('continent == \"North America\"')\\\n",
" .to_crs(epsg=3083)\n",
"urban = geopandas.GeoDataFrame(\n",
" {'geometry':cities.to_crs(epsg=3083)\\\n",
" .buffer(50000)}, \\\n",
" crs = namerica.crs)\n",
" \n",
"rural = geopandas.overlay(namerica, urban, how='difference')\n",
"\n",
"print('Rural: ', rural.unary_union.area * 1e-6, ' Km^2')\n",
"print('Rural is %.2f%% of the total extent'%\n",
" (rural.unary_union.area * 100 / \n",
" namerica.unary_union.area))\n",
"-->"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
}
],
"metadata": {
Expand All @@ -318,7 +443,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.5"
"version": "3.6.5"
}
},
"nbformat": 4,
Expand Down