Skip to content

Commit b2dbe3d

Browse files
authored
Merge pull request #100 from NERDSITU/99-osmnx-project_gdf-api-change
Fix and version bump `1.0.1`
2 parents 9fdc114 + de99e56 commit b2dbe3d

26 files changed

+1035535
-1078453
lines changed

.github/workflows/lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ jobs:
5353
run: pip install pylint
5454

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

5959
- name: Lint Tests
60-
run: pylint -d E0401 -d R0801 tests/
60+
run: pylint -d E0401,R0801,R0917 tests/
6161
# also ignore code repetition in tests

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ jobs:
6969

7070
name: ${{ matrix.submodule.name }} (${{ matrix.python-version }} on ${{ matrix.os }})
7171
runs-on: ${{ matrix.os }}
72+
timeout-minutes: 60
7273
defaults:
7374
run:
7475
shell: bash -el {0}

docs/changelog.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
Changelog
33
*********
44

5+
Version 1.0.1 (2024-12-04)
6+
**************************
7+
8+
* 🧹 Lint: Reconfigured linting settings.
9+
* 🐛 Fixes: Removed unused Haversine distance function and adapted to `osmnx` API changes.
10+
* 🛠️ Update: Updated `test.yml` for artifacts v4.4.0 breaking change.
11+
* 📝 Documentation: Various updates including changelog, badge links,
12+
mobile optimization, GitHub handles, installation instructions, `CITATION.cff`, and `paper.md`.
13+
514
Version 1.0.0 (2024-08-12)
615
**************************
716

docs/conf.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#
1212
import os
1313
import sys
14+
from datetime import datetime
1415

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

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

2425
project = "superblockify"
25-
copyright = "2023-2024, superblockify developers"
26+
copyright = f"2023-{datetime.now().year}, superblockify developers"
2627
author = "superblockify developers"
27-
release = "1.0.0"
28+
release = "1.0.1"
2829

2930
# -- General configuration ---------------------------------------------------
3031
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

docs/guide/30_population_density.myst

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ from rasterstats import zonal_stats
4848
## 1. Area Boundary
4949

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

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

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

423427
Returns
424428
-------
@@ -427,7 +431,8 @@ def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=No
427431
"""
428432
fig, axe = plt.subplots(figsize=(6, 6))
429433
pop_sum = 0
430-
for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [pop_raster_files]:
434+
for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [
435+
pop_raster_files]:
431436
# Window of place, buffered by 100m
432437
with rasterio.open(pop_raster_file) as src:
433438
window = src.window(*place_gdf.buffer(100).total_bounds)
@@ -442,6 +447,9 @@ def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=No
442447
pop_raster = pop_raster / resample_factor ** 2 # Correct for resampling
443448
# Set masked values to 0
444449
pop_raster = pop_raster.filled(0)
450+
# Cut off low values
451+
pop_raster[pop_raster < low_cutoff] = 0
452+
445453
# Get population
446454
zs_place = zonal_stats(place_gdf_raster_crs, pop_raster, affine=affine,
447455
stats="sum", nodata=0)

docs/guide/31_tessellation.myst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ that might come to one's mind is the convex hull of the linestrings.
7070

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

337337
```{code-cell} ipython3
338-
hull = shp.Polygon(edges.unary_union.buffer(100).exterior)
338+
hull = shp.Polygon(edges.union_all().buffer(100).exterior)
339339
# interpolate points along the hull - double the distance
340340
hull_points = shp.line_interpolate_point(
341341
hull.boundary,

docs/guide/32_edge_population.myst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,11 @@ For that, we take the union of all road cells and get the bounding box of it. Wh
124124
looking at the union, the _skewness_ of our projection is visible.
125125

126126
```{code-cell} ipython3
127-
lc_road_cells.unary_union
127+
lc_road_cells.union_all()
128128
```
129129

130130
```{code-cell} ipython3
131-
lc_bbox = lc_road_cells.unary_union.bounds
131+
lc_bbox = lc_road_cells.union_all().bounds
132132
lc_ghsl = get_ghsl(lc_bbox)
133133
```
134134

examples/06-population-density.ipynb

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@
8181
},
8282
"outputs": [],
8383
"source": [
84-
"bogota_gdf = ox.geocode_to_gdf('Bogotá, Colombia')\n",
84+
"bogota_gdf = ox.geocode_to_gdf('Bogotá, Capital District, RAP (Especial) Central, Colombia')\n",
8585
"# Project to UTM, so we can treat it as flat Cartesian coordinates (meters)\n",
86-
"bogota_gdf = ox.project_gdf(bogota_gdf)\n",
86+
"bogota_gdf = ox.projection.project_gdf(bogota_gdf)\n",
8787
"print(f\"The area of Bogotá is {round(bogota_gdf.area[0] / 10 ** 6, 2)} km²\")\n",
8888
"bogota_gdf.explore()"
8989
]
@@ -681,7 +681,9 @@
681681
},
682682
"outputs": [],
683683
"source": [
684-
"def get_population(place_gdf, pop_raster_files, resample_factor=1, place_name=None):\n",
684+
"def get_population(\n",
685+
" place_gdf, pop_raster_files, resample_factor=1, place_name=None, low_cutoff=0\n",
686+
"):\n",
685687
" \"\"\"Get the population for a place.\n",
686688
"\n",
687689
" Parameters\n",
@@ -695,6 +697,8 @@
695697
" up-scaling.\n",
696698
" place_name : str, optional\n",
697699
" Name of the place. The default is None.\n",
700+
" low_cutoff : float, optional\n",
701+
" The least considered value for the population. The default is 0.\n",
698702
"\n",
699703
" Returns\n",
700704
" -------\n",
@@ -703,7 +707,8 @@
703707
" \"\"\"\n",
704708
" fig, axe = plt.subplots(figsize=(6, 6))\n",
705709
" pop_sum = 0\n",
706-
" for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [pop_raster_files]:\n",
710+
" for pop_raster_file in pop_raster_files if isinstance(pop_raster_files, list) else [\n",
711+
" pop_raster_files]:\n",
707712
" # Window of place, buffered by 100m\n",
708713
" with rasterio.open(pop_raster_file) as src:\n",
709714
" window = src.window(*place_gdf.buffer(100).total_bounds)\n",
@@ -718,6 +723,9 @@
718723
" pop_raster = pop_raster / resample_factor ** 2 # Correct for resampling\n",
719724
" # Set masked values to 0\n",
720725
" pop_raster = pop_raster.filled(0)\n",
726+
" # Cut off low values\n",
727+
" pop_raster[pop_raster < low_cutoff] = 0\n",
728+
"\n",
721729
" # Get population\n",
722730
" zs_place = zonal_stats(place_gdf_raster_crs, pop_raster, affine=affine,\n",
723731
" stats=\"sum\", nodata=0)\n",

examples/07-superblock-boundary.ipynb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
"outputs": [],
126126
"source": [
127127
"# From subgraph_edges we want to get a hull that encloses all edges\n",
128-
"convex_hull = subgraph_edges.unary_union.convex_hull\n",
128+
"convex_hull = subgraph_edges.union_all().convex_hull\n",
129129
"# Make gdf from convex hull with the same crs as the subgraph\n",
130130
"convex_hull_gdf = gpd.GeoDataFrame(\n",
131131
" geometry=[convex_hull], crs=subgraph_edges.crs\n",
@@ -163,7 +163,7 @@
163163
"outputs": [],
164164
"source": [
165165
"# Shapely MultiLineString geometry\n",
166-
"subgraph_edges.explode().unary_union.boundary\n"
166+
"subgraph_edges.explode().union_all().boundary\n"
167167
]
168168
},
169169
{
@@ -179,7 +179,7 @@
179179
"source": [
180180
"# Concave hull of the edges\n",
181181
"shp.concave_hull(\n",
182-
" subgraph_edges.unary_union,\n",
182+
" subgraph_edges.union_all(),\n",
183183
" ratio=0.4,\n",
184184
" allow_holes=True,\n",
185185
")"
@@ -199,7 +199,7 @@
199199
"def plot_concave_hull(ax, subgraph_edges, ratio=0.4, allow_holes=False,\n",
200200
" color=\"crimson\"):\n",
201201
" concave_hull = shp.concave_hull(\n",
202-
" subgraph_edges.unary_union,\n",
202+
" subgraph_edges.union_all(),\n",
203203
" ratio=ratio,\n",
204204
" allow_holes=allow_holes,\n",
205205
" )\n",
@@ -281,7 +281,7 @@
281281
"source": [
282282
"def border_from_subgraph(subgraph, buffer=2):\n",
283283
" edges = ox.graph_to_gdfs(subgraph, nodes=False, edges=True)\n",
284-
" return edges.unary_union.buffer(buffer, cap_style='flat').buffer(-buffer / 2)"
284+
" return edges.union_all().buffer(buffer, cap_style='flat').buffer(-buffer / 2)"
285285
]
286286
},
287287
{
@@ -341,7 +341,7 @@
341341
" Does work well with small buffer values.\"\"\"\n",
342342
" edges = ox.graph_to_gdfs(subgraph, nodes=False, edges=True)\n",
343343
" # First buffer with flat cap style to avoid self-intersections\n",
344-
" polygon = shp.Polygon(edges.unary_union.buffer(2 * buffer, cap_style='flat')\n",
344+
" polygon = shp.Polygon(edges.union_all().buffer(2 * buffer, cap_style='flat')\n",
345345
" .exterior)\n",
346346
" # Simplify the polygon to remove small artifacts of flat cap style at curved edges\n",
347347
" # polygon = polygon.simplify(buffer*2, preserve_topology=True)\n",
@@ -378,7 +378,7 @@
378378
" Works better with larger buffer values.\"\"\"\n",
379379
" edges = ox.graph_to_gdfs(subgraph, nodes=False, edges=True)\n",
380380
" # First buffer with flat cap style to avoid self-intersections\n",
381-
" lin_ring = edges.unary_union.buffer(buffer, cap_style='flat').exterior\n",
381+
" lin_ring = edges.union_all().buffer(buffer, cap_style='flat').exterior\n",
382382
" # Smoothen the linear ring, taking the midpoints of the edges\n",
383383
" lin_ring = shp.LinearRing(\n",
384384
" [shp.Point((x1 + x2) / 2, (y1 + y2) / 2) for (x1, y1), (x2, y2) in zip(\n",
@@ -543,7 +543,7 @@
543543
" primary_barriers=gpd.GeoDataFrame(\n",
544544
" geometry=part.graph.graph[\"boundary\"].difference(\n",
545545
" gpd.GeoSeries(edges_sparsified.buffer(5)\n",
546-
" .unary_union)),\n",
546+
" .union_all())),\n",
547547
" crs=part.graph.graph[\"boundary_crs\"]\n",
548548
" ),\n",
549549
" limit= #mm.buffered_limit(borders, 1).convex_hull,\n",
@@ -818,7 +818,7 @@
818818
" part.graph.nodes[node][\"cell\"] = node_poly_gdf.loc[node, \"geometry\"]\n",
819819
"# For each partition create boundary as union of cells\n",
820820
"for p, p_order in zip(part.partitions, part.get_partition_nodes()):\n",
821-
" p[\"boundary\"] = shp.unary_union(\n",
821+
" p[\"boundary\"] = shp.union_all()(\n",
822822
" [part.graph.nodes[node][\"cell\"] for node in p_order[\"nodes\"]])"
823823
]
824824
},
@@ -990,7 +990,7 @@
990990
"source": [
991991
"# get hull from the graph boundary\n",
992992
"# hull = part.graph.graph[\"boundary\"]\n",
993-
"hull = shp.Polygon(edges.unary_union.buffer(100).exterior)\n",
993+
"hull = shp.Polygon(edges.union_all().buffer(100).exterior)\n",
994994
"hull"
995995
]
996996
},

superblockify/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""superblockify package version."""
22

3-
__version__ = "1.0.0"
3+
__version__ = "1.0.1"

superblockify/cities.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ place_lists:
120120
- 1572779
121121
pop_GHSL2023: 328740.3926395578
122122
Liechtenstein:
123-
query: Liechtenstein, Europe
123+
query: Liechtenstein
124124
country: LI
125125
region: EU
126126
nominatim link:
127-
- https://nominatim.openstreetmap.org/ui/search.html?q=Liechtenstein,+Europe
127+
- https://nominatim.openstreetmap.org/ui/search.html?q=Liechtenstein
128128
OSM relation:
129129
- https://www.openstreetmap.org/relation/1155955
130130
osm_id:

0 commit comments

Comments
 (0)