Skip to content

Commit

Permalink
Merge pull request #100 from NERDSITU/99-osmnx-project_gdf-api-change
Browse files Browse the repository at this point in the history
Fix and version bump `1.0.1`
  • Loading branch information
cbueth authored Dec 4, 2024
2 parents 9fdc114 + de99e56 commit b2dbe3d
Show file tree
Hide file tree
Showing 26 changed files with 1,035,535 additions and 1,078,453 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ jobs:
run: pip install pylint

- name: Lint Source Code
run: pylint -d E0401 superblockify/
run: pylint -d E0401,R0917 superblockify/
# ignore import-errors first, analyze later with tests in anaconda environment

- name: Lint Tests
run: pylint -d E0401 -d R0801 tests/
run: pylint -d E0401,R0801,R0917 tests/
# also ignore code repetition in tests
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ jobs:

name: ${{ matrix.submodule.name }} (${{ matrix.python-version }} on ${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 60
defaults:
run:
shell: bash -el {0}
Expand Down
9 changes: 9 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
Changelog
*********

Version 1.0.1 (2024-12-04)
**************************

* 🧹 Lint: Reconfigured linting settings.
* 🐛 Fixes: Removed unused Haversine distance function and adapted to `osmnx` API changes.
* 🛠️ Update: Updated `test.yml` for artifacts v4.4.0 breaking change.
* 📝 Documentation: Various updates including changelog, badge links,
mobile optimization, GitHub handles, installation instructions, `CITATION.cff`, and `paper.md`.

Version 1.0.0 (2024-08-12)
**************************

Expand Down
5 changes: 3 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#
import os
import sys
from datetime import datetime

sys.path.insert(0, os.path.abspath(".."))

Expand All @@ -22,9 +23,9 @@
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = "superblockify"
copyright = "2023-2024, superblockify developers"
copyright = f"2023-{datetime.now().year}, superblockify developers"
author = "superblockify developers"
release = "1.0.0"
release = "1.0.1"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
16 changes: 12 additions & 4 deletions docs/guide/30_population_density.myst
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ from rasterstats import zonal_stats
## 1. Area Boundary

```{code-cell} ipython3
bogota_gdf = ox.geocode_to_gdf('Bogotá, Colombia')
bogota_gdf = ox.geocode_to_gdf('Bogotá, Capital District, RAP (Especial) Central, Colombia')
# Project to UTM, so we can treat it as flat Cartesian coordinates (meters)
bogota_gdf = ox.project_gdf(bogota_gdf)
bogota_gdf = ox.projection.project_gdf(bogota_gdf)
print(f"The area of Bogotá is {round(bogota_gdf.area[0] / 10 ** 6, 2)} km²")
bogota_gdf.explore()
```
Expand Down Expand Up @@ -405,7 +405,9 @@ One such example is the city of Jönköping in Sweden, it falls on two tiles.

```{code-cell} ipython3
:tags: [hide-input]
def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=None):
def get_population(
place_gdf, pop_raster_files, resample_factor=1, place_name=None, low_cutoff=0
):
"""Get the population for a place.

Parameters
Expand All @@ -419,6 +421,8 @@ def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=No
up-scaling.
place_name : str, optional
Name of the place. The default is None.
low_cutoff : float, optional
The least considered value for the population. The default is 0.

Returns
-------
Expand All @@ -427,7 +431,8 @@ def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=No
"""
fig, axe = plt.subplots(figsize=(6, 6))
pop_sum = 0
for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [pop_raster_files]:
for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [
pop_raster_files]:
# Window of place, buffered by 100m
with rasterio.open(pop_raster_file) as src:
window = src.window(*place_gdf.buffer(100).total_bounds)
Expand All @@ -442,6 +447,9 @@ def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=No
pop_raster = pop_raster / resample_factor ** 2 # Correct for resampling
# Set masked values to 0
pop_raster = pop_raster.filled(0)
# Cut off low values
pop_raster[pop_raster < low_cutoff] = 0

# Get population
zs_place = zonal_stats(place_gdf_raster_crs, pop_raster, affine=affine,
stats="sum", nodata=0)
Expand Down
8 changes: 4 additions & 4 deletions docs/guide/31_tessellation.myst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ that might come to one's mind is the convex hull of the linestrings.

```{code-cell} ipython3
# From subgraph_edges we want to get a hull that encloses all edges
convex_hull = subgraph_edges.unary_union.convex_hull
convex_hull = subgraph_edges.union_all().convex_hull
# Make gdf from convex hull with the same crs as the subgraph
convex_hull_gdf = gpd.GeoDataFrame(
geometry=[convex_hull], crs=subgraph_edges.crs
Expand Down Expand Up @@ -102,7 +102,7 @@ from numpy import linspace
def plot_concave_hull(ax, subgraph_edges, ratio=0.4, allow_holes=False,
color="crimson"):
concave_hull = shp.concave_hull(
subgraph_edges.unary_union,
subgraph_edges.union_all(),
ratio=ratio,
allow_holes=allow_holes,
)
Expand Down Expand Up @@ -186,7 +186,7 @@ each other, we'll buffer using a flat cap style.
Does work well with small buffer values."""
edges = ox.graph_to_gdfs(subgraph, nodes=False, edges=True)
# First buffer with flat cap style to avoid self-intersections
polygon = shp.Polygon(edges.unary_union.buffer(2 * buffer, cap_style='flat')
polygon = shp.Polygon(edges.union_all().buffer(2 * buffer, cap_style='flat')
.exterior)
# Simplify the polygon to remove small artifacts of flat cap style at curved edges
# polygon = polygon.simplify(buffer*2, preserve_topology=True)
Expand Down Expand Up @@ -335,7 +335,7 @@ geometries. Then we can also split up the hull into points and add them to the p
array.

```{code-cell} ipython3
hull = shp.Polygon(edges.unary_union.buffer(100).exterior)
hull = shp.Polygon(edges.union_all().buffer(100).exterior)
# interpolate points along the hull - double the distance
hull_points = shp.line_interpolate_point(
hull.boundary,
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/32_edge_population.myst
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ For that, we take the union of all road cells and get the bounding box of it. Wh
looking at the union, the _skewness_ of our projection is visible.

```{code-cell} ipython3
lc_road_cells.unary_union
lc_road_cells.union_all()
```

```{code-cell} ipython3
lc_bbox = lc_road_cells.unary_union.bounds
lc_bbox = lc_road_cells.union_all().bounds
lc_ghsl = get_ghsl(lc_bbox)
```

Expand Down
16 changes: 12 additions & 4 deletions examples/06-population-density.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@
},
"outputs": [],
"source": [
"bogota_gdf = ox.geocode_to_gdf('Bogotá, Colombia')\n",
"bogota_gdf = ox.geocode_to_gdf('Bogotá, Capital District, RAP (Especial) Central, Colombia')\n",
"# Project to UTM, so we can treat it as flat Cartesian coordinates (meters)\n",
"bogota_gdf = ox.project_gdf(bogota_gdf)\n",
"bogota_gdf = ox.projection.project_gdf(bogota_gdf)\n",
"print(f\"The area of Bogotá is {round(bogota_gdf.area[0] / 10 ** 6, 2)} km²\")\n",
"bogota_gdf.explore()"
]
Expand Down Expand Up @@ -681,7 +681,9 @@
},
"outputs": [],
"source": [
"def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=None):\n",
"def get_population(\n",
" place_gdf, pop_raster_files, resample_factor=1, place_name=None, low_cutoff=0\n",
"):\n",
" \"\"\"Get the population for a place.\n",
"\n",
" Parameters\n",
Expand All @@ -695,6 +697,8 @@
" up-scaling.\n",
" place_name : str, optional\n",
" Name of the place. The default is None.\n",
" low_cutoff : float, optional\n",
" The least considered value for the population. The default is 0.\n",
"\n",
" Returns\n",
" -------\n",
Expand All @@ -703,7 +707,8 @@
" \"\"\"\n",
" fig, axe = plt.subplots(figsize=(6, 6))\n",
" pop_sum = 0\n",
" for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [pop_raster_files]:\n",
" for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [\n",
" pop_raster_files]:\n",
" # Window of place, buffered by 100m\n",
" with rasterio.open(pop_raster_file) as src:\n",
" window = src.window(*place_gdf.buffer(100).total_bounds)\n",
Expand All @@ -718,6 +723,9 @@
" pop_raster = pop_raster / resample_factor ** 2 # Correct for resampling\n",
" # Set masked values to 0\n",
" pop_raster = pop_raster.filled(0)\n",
" # Cut off low values\n",
" pop_raster[pop_raster < low_cutoff] = 0\n",
"\n",
" # Get population\n",
" zs_place = zonal_stats(place_gdf_raster_crs, pop_raster, affine=affine,\n",
" stats=\"sum\", nodata=0)\n",
Expand Down
20 changes: 10 additions & 10 deletions examples/07-superblock-boundary.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
"outputs": [],
"source": [
"# From subgraph_edges we want to get a hull that encloses all edges\n",
"convex_hull = subgraph_edges.unary_union.convex_hull\n",
"convex_hull = subgraph_edges.union_all().convex_hull\n",
"# Make gdf from convex hull with the same crs as the subgraph\n",
"convex_hull_gdf = gpd.GeoDataFrame(\n",
" geometry=[convex_hull], crs=subgraph_edges.crs\n",
Expand Down Expand Up @@ -163,7 +163,7 @@
"outputs": [],
"source": [
"# Shapely MultiLineString geometry\n",
"subgraph_edges.explode().unary_union.boundary\n"
"subgraph_edges.explode().union_all().boundary\n"
]
},
{
Expand All @@ -179,7 +179,7 @@
"source": [
"# Concave hull of the edges\n",
"shp.concave_hull(\n",
" subgraph_edges.unary_union,\n",
" subgraph_edges.union_all(),\n",
" ratio=0.4,\n",
" allow_holes=True,\n",
")"
Expand All @@ -199,7 +199,7 @@
"def plot_concave_hull(ax, subgraph_edges, ratio=0.4, allow_holes=False,\n",
" color=\"crimson\"):\n",
" concave_hull = shp.concave_hull(\n",
" subgraph_edges.unary_union,\n",
" subgraph_edges.union_all(),\n",
" ratio=ratio,\n",
" allow_holes=allow_holes,\n",
" )\n",
Expand Down Expand Up @@ -281,7 +281,7 @@
"source": [
"def border_from_subgraph(subgraph, buffer=2):\n",
" edges = ox.graph_to_gdfs(subgraph, nodes=False, edges=True)\n",
" return edges.unary_union.buffer(buffer, cap_style='flat').buffer(-buffer / 2)"
" return edges.union_all().buffer(buffer, cap_style='flat').buffer(-buffer / 2)"
]
},
{
Expand Down Expand Up @@ -341,7 +341,7 @@
" Does work well with small buffer values.\"\"\"\n",
" edges = ox.graph_to_gdfs(subgraph, nodes=False, edges=True)\n",
" # First buffer with flat cap style to avoid self-intersections\n",
" polygon = shp.Polygon(edges.unary_union.buffer(2 * buffer, cap_style='flat')\n",
" polygon = shp.Polygon(edges.union_all().buffer(2 * buffer, cap_style='flat')\n",
" .exterior)\n",
" # Simplify the polygon to remove small artifacts of flat cap style at curved edges\n",
" # polygon = polygon.simplify(buffer*2, preserve_topology=True)\n",
Expand Down Expand Up @@ -378,7 +378,7 @@
" Works better with larger buffer values.\"\"\"\n",
" edges = ox.graph_to_gdfs(subgraph, nodes=False, edges=True)\n",
" # First buffer with flat cap style to avoid self-intersections\n",
" lin_ring = edges.unary_union.buffer(buffer, cap_style='flat').exterior\n",
" lin_ring = edges.union_all().buffer(buffer, cap_style='flat').exterior\n",
" # Smoothen the linear ring, taking the midpoints of the edges\n",
" lin_ring = shp.LinearRing(\n",
" [shp.Point((x1 + x2) / 2, (y1 + y2) / 2) for (x1, y1), (x2, y2) in zip(\n",
Expand Down Expand Up @@ -543,7 +543,7 @@
" primary_barriers=gpd.GeoDataFrame(\n",
" geometry=part.graph.graph[\"boundary\"].difference(\n",
" gpd.GeoSeries(edges_sparsified.buffer(5)\n",
" .unary_union)),\n",
" .union_all())),\n",
" crs=part.graph.graph[\"boundary_crs\"]\n",
" ),\n",
" limit= #mm.buffered_limit(borders, 1).convex_hull,\n",
Expand Down Expand Up @@ -818,7 +818,7 @@
" part.graph.nodes[node][\"cell\"] = node_poly_gdf.loc[node, \"geometry\"]\n",
"# For each partition create boundary as union of cells\n",
"for p, p_order in zip(part.partitions, part.get_partition_nodes()):\n",
" p[\"boundary\"] = shp.unary_union(\n",
" p[\"boundary\"] = shp.union_all()(\n",
" [part.graph.nodes[node][\"cell\"] for node in p_order[\"nodes\"]])"
]
},
Expand Down Expand Up @@ -990,7 +990,7 @@
"source": [
"# get hull from the graph boundary\n",
"# hull = part.graph.graph[\"boundary\"]\n",
"hull = shp.Polygon(edges.unary_union.buffer(100).exterior)\n",
"hull = shp.Polygon(edges.union_all().buffer(100).exterior)\n",
"hull"
]
},
Expand Down
2 changes: 1 addition & 1 deletion superblockify/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""superblockify package version."""

__version__ = "1.0.0"
__version__ = "1.0.1"
4 changes: 2 additions & 2 deletions superblockify/cities.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,11 @@ place_lists:
- 1572779
pop_GHSL2023: 328740.3926395578
Liechtenstein:
query: Liechtenstein, Europe
query: Liechtenstein
country: LI
region: EU
nominatim link:
- https://nominatim.openstreetmap.org/ui/search.html?q=Liechtenstein,+Europe
- https://nominatim.openstreetmap.org/ui/search.html?q=Liechtenstein
OSM relation:
- https://www.openstreetmap.org/relation/1155955
osm_id:
Expand Down
Loading

0 comments on commit b2dbe3d

Please sign in to comment.