Adjacency neighbourhood
In [1]:
Copied!
import geopandas as gpd
import numpy as np
from shapely.geometry import Point
from srai.constants import WGS84_CRS
from srai.neighbourhoods import AdjacencyNeighbourhood
from srai.plotting.folium_wrapper import plot_all_neighbourhood, plot_neighbours, plot_regions
from srai.regionalizers import (
AdministrativeBoundaryRegionalizer,
VoronoiRegionalizer,
geocode_to_region_gdf,
)
import geopandas as gpd
import numpy as np
from shapely.geometry import Point
from srai.constants import WGS84_CRS
from srai.neighbourhoods import AdjacencyNeighbourhood
from srai.plotting.folium_wrapper import plot_all_neighbourhood, plot_neighbours, plot_regions
from srai.regionalizers import (
AdministrativeBoundaryRegionalizer,
VoronoiRegionalizer,
geocode_to_region_gdf,
)
Adjacency Neighbourhood¶
It can generate neighbourhoods for all geodataframes with touching geometries.
Real boundaries example - Italy¶
In [2]:
Copied!
it_gdf = geocode_to_region_gdf(query=["R365331"], by_osmid=True)
plot_regions(it_gdf)
it_gdf = geocode_to_region_gdf(query=["R365331"], by_osmid=True)
plot_regions(it_gdf)
Out[2]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [3]:
Copied!
regionalizer = AdministrativeBoundaryRegionalizer(admin_level=4)
it_regions_gdf = regionalizer.transform(it_gdf)
regionalizer = AdministrativeBoundaryRegionalizer(admin_level=4)
it_regions_gdf = regionalizer.transform(it_gdf)
Loading boundaries: 0: 0%| | 0/6 [00:00<?, ?it/s]
Loading boundaries: 1: 0%| | 0/6 [00:00<?, ?it/s]
Loading boundaries: 2: 0%| | 0/6 [00:00<?, ?it/s]
Loading boundaries: 3: 0%| | 0/6 [00:00<?, ?it/s]
Loading boundaries: 4: 0%| | 0/6 [00:00<?, ?it/s]
Loading boundaries: 5: 0%| | 0/6 [00:01<?, ?it/s]
Loading boundaries: 6: 0%| | 0/6 [00:01<?, ?it/s]
Loading boundaries: 7: 0%| | 0/6 [00:01<?, ?it/s]
Loading boundaries: 8: 0%| | 0/6 [00:02<?, ?it/s]
Loading boundaries: 9: 0%| | 0/6 [00:02<?, ?it/s]
Loading boundaries: 10: 0%| | 0/6 [00:02<?, ?it/s]
Loading boundaries: 11: 0%| | 0/6 [00:03<?, ?it/s]
Loading boundaries: 12: 0%| | 0/6 [00:03<?, ?it/s]
Loading boundaries: 13: 0%| | 0/6 [00:04<?, ?it/s]
Loading boundaries: 14: 0%| | 0/6 [00:04<?, ?it/s]
Loading boundaries: 15: 0%| | 0/6 [00:05<?, ?it/s]
Loading boundaries: 16: 0%| | 0/6 [00:05<?, ?it/s]
Loading boundaries: 17: 0%| | 0/6 [00:06<?, ?it/s]
Loading boundaries: 18: 0%| | 0/6 [00:06<?, ?it/s]
Loading boundaries: 19: 0%| | 0/6 [00:07<?, ?it/s]
Loading boundaries: 20: 0%| | 0/6 [00:07<?, ?it/s]
Loading boundaries: 21: 0%| | 0/6 [00:08<?, ?it/s]
Loading boundaries: 22: 0%| | 0/6 [00:08<?, ?it/s]
Loading boundaries: 23: 0%| | 0/6 [00:09<?, ?it/s]
Loading boundaries: 24: 0%| | 0/6 [00:09<?, ?it/s]
Loading boundaries: 25: 0%| | 0/6 [00:10<?, ?it/s]
Loading boundaries: 26: 0%| | 0/6 [00:10<?, ?it/s]
Loading boundaries: 27: 0%| | 0/6 [00:11<?, ?it/s]
Loading boundaries: 28: 0%| | 0/6 [00:12<?, ?it/s]
Loading boundaries: 29: 0%| | 0/6 [00:13<?, ?it/s]
Loading boundaries: 30: 0%| | 0/6 [00:13<?, ?it/s]
Loading boundaries: 31: 0%| | 0/6 [00:14<?, ?it/s]
Loading boundaries: 32: 0%| | 0/6 [00:14<?, ?it/s]
Loading boundaries: 33: 0%| | 0/6 [00:15<?, ?it/s]
Loading boundaries: 34: 0%| | 0/6 [00:15<?, ?it/s]
Loading boundaries: 35: 0%| | 0/6 [00:16<?, ?it/s]
Loading boundaries: 36: 0%| | 0/6 [00:16<?, ?it/s]
Loading boundaries: 37: 0%| | 0/6 [00:17<?, ?it/s]
Loading boundaries: 38: 0%| | 0/6 [00:17<?, ?it/s]
Loading boundaries: 39: 0%| | 0/6 [00:18<?, ?it/s]
Loading boundaries: 40: 0%| | 0/6 [00:19<?, ?it/s]
Loading boundaries: 41: 0%| | 0/6 [00:20<?, ?it/s]
Loading boundaries: 42: 0%| | 0/6 [00:21<?, ?it/s]
Loading boundaries: 43: 0%| | 0/6 [00:22<?, ?it/s]
Loading boundaries: 44: 0%| | 0/6 [00:22<?, ?it/s]
Loading boundaries: 45: 0%| | 0/6 [00:23<?, ?it/s]
Loading boundaries: 46: 0%| | 0/6 [00:24<?, ?it/s]
Loading boundaries: 47: 0%| | 0/6 [00:25<?, ?it/s]
Loading boundaries: 48: 0%| | 0/6 [00:25<?, ?it/s]
Loading boundaries: 49: 0%| | 0/6 [00:26<?, ?it/s]
Loading boundaries: 50: 0%| | 0/6 [00:27<?, ?it/s]
Loading boundaries: 51: 0%| | 0/6 [00:27<?, ?it/s]
Loading boundaries: 52: 0%| | 0/6 [00:28<?, ?it/s]
Loading boundaries: 53: 0%| | 0/6 [00:28<?, ?it/s]
Loading boundaries: 54: 0%| | 0/6 [00:29<?, ?it/s]
Loading boundaries: 55: 0%| | 0/6 [00:30<?, ?it/s]
Loading boundaries: 56: 0%| | 0/6 [00:31<?, ?it/s]
Loading boundaries: 57: 0%| | 0/6 [00:32<?, ?it/s]
Loading boundaries: 58: 0%| | 0/6 [00:32<?, ?it/s]
Loading boundaries: 59: 0%| | 0/6 [00:33<?, ?it/s]
Loading boundaries: 60: 0%| | 0/6 [00:34<?, ?it/s]
Loading boundaries: 61: 0%| | 0/6 [00:34<?, ?it/s]
Loading boundaries: 62: 0%| | 0/6 [00:35<?, ?it/s]
Loading boundaries: 63: 0%| | 0/6 [00:36<?, ?it/s]
Loading boundaries: 64: 0%| | 0/6 [00:37<?, ?it/s]
Loading boundaries: 65: 0%| | 0/6 [00:38<?, ?it/s]
Loading boundaries: 66: 0%| | 0/6 [00:41<?, ?it/s]
Loading boundaries: 67: 0%| | 0/6 [00:43<?, ?it/s]
Loading boundaries: 68: 0%| | 0/6 [00:47<?, ?it/s]
Loading boundaries: 68: 17%|████████████████████████████▎ | 1/6 [00:47<03:55, 47.19s/it]
Loading boundaries: 68: 33%|████████████████████████████████████████████████████████▋ | 2/6 [00:52<01:30, 22.73s/it]
Loading boundaries: 68: 50%|█████████████████████████████████████████████████████████████████████████████████████ | 3/6 [00:53<00:37, 12.58s/it]
Loading boundaries: 68: 67%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████▎ | 4/6 [00:54<00:16, 8.11s/it]
Loading boundaries: 68: 83%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▋ | 5/6 [00:54<00:05, 5.33s/it]
Loading boundaries: 68: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6/6 [00:56<00:00, 3.97s/it]
Loading boundaries: 68: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6/6 [00:56<00:00, 9.38s/it]
/root/development/srai/srai/regionalizers/administrative_boundary_regionalizer.py:169: FutureWarning: `unary_union` returned None due to all-None GeoSeries. In future, `unary_union` will return 'GEOMETRYCOLLECTION EMPTY' instead. ].geometry.unary_union
In [4]:
Copied!
plot_regions(it_regions_gdf)
plot_regions(it_regions_gdf)
Out[4]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [5]:
Copied!
neighbourhood = AdjacencyNeighbourhood(it_regions_gdf)
neighbourhood = AdjacencyNeighbourhood(it_regions_gdf)
Nearest neighbours¶
In [6]:
Copied!
region_id = "Lazio"
neighbours = neighbourhood.get_neighbours(region_id)
neighbours
region_id = "Lazio"
neighbours = neighbourhood.get_neighbours(region_id)
neighbours
Out[6]:
{'Abruzzo', 'Campania', 'Marche', 'Molise', 'Tuscany', 'Umbria'}
In [7]:
Copied!
plot_neighbours(it_regions_gdf, region_id, neighbours)
plot_neighbours(it_regions_gdf, region_id, neighbours)
Out[7]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Neighbours at a distance¶
In [8]:
Copied!
region_id = "Basilicata"
neighbours = neighbourhood.get_neighbours_at_distance(region_id, 2)
neighbours
region_id = "Basilicata"
neighbours = neighbourhood.get_neighbours_at_distance(region_id, 2)
neighbours
Out[8]:
{'Lazio', 'Molise'}
In [9]:
Copied!
plot_neighbours(it_regions_gdf, region_id, neighbours)
plot_neighbours(it_regions_gdf, region_id, neighbours)
Out[9]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Regions without neighbours¶
In [10]:
Copied!
region_id = "Sardinia"
neighbours = neighbourhood.get_neighbours(region_id)
neighbours
region_id = "Sardinia"
neighbours = neighbourhood.get_neighbours(region_id)
neighbours
Out[10]:
set()
In [11]:
Copied!
plot_neighbours(it_regions_gdf, region_id, neighbours)
plot_neighbours(it_regions_gdf, region_id, neighbours)
Out[11]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Plotting all neighbourhood¶
In [12]:
Copied!
region_id = "Campania"
plot_all_neighbourhood(it_regions_gdf, region_id, neighbourhood)
region_id = "Campania"
plot_all_neighbourhood(it_regions_gdf, region_id, neighbourhood)
Out[12]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Voronoi example - Australia¶
In [13]:
Copied!
au_gdf = geocode_to_region_gdf(query=["R80500"], by_osmid=True)
plot_regions(au_gdf)
au_gdf = geocode_to_region_gdf(query=["R80500"], by_osmid=True)
plot_regions(au_gdf)
Out[13]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [14]:
Copied!
def generate_random_points(shape, n_points=500):
"""Generates random points."""
minx, miny, maxx, maxy = shape.bounds
pts = []
rng = np.random.default_rng()
while len(pts) < 4:
randx = rng.uniform(minx, maxx, n_points)
randy = rng.uniform(miny, maxy, n_points)
coords = np.vstack((randx, randy)).T
# use only the points inside the geographic area
pts = [p for p in list(map(Point, coords)) if p.within(shape)]
del coords # not used any more
return pts
def generate_random_points(shape, n_points=500):
"""Generates random points."""
minx, miny, maxx, maxy = shape.bounds
pts = []
rng = np.random.default_rng()
while len(pts) < 4:
randx = rng.uniform(minx, maxx, n_points)
randy = rng.uniform(miny, maxy, n_points)
coords = np.vstack((randx, randy)).T
# use only the points inside the geographic area
pts = [p for p in list(map(Point, coords)) if p.within(shape)]
del coords # not used any more
return pts
In [15]:
Copied!
pts = generate_random_points(au_gdf.geometry[0])
au_seeds_gdf = gpd.GeoDataFrame(
{"geometry": pts},
index=list(range(len(pts))),
crs=WGS84_CRS,
)
pts = generate_random_points(au_gdf.geometry[0])
au_seeds_gdf = gpd.GeoDataFrame(
{"geometry": pts},
index=list(range(len(pts))),
crs=WGS84_CRS,
)
/root/development/srai/.venv/lib/python3.10/site-packages/geopandas/geoseries.py:641: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]` val = getattr(super(), mtd)(*args, **kwargs)
In [16]:
Copied!
vr = VoronoiRegionalizer(seeds=au_seeds_gdf)
au_result_gdf = vr.transform(gdf=au_gdf)
vr = VoronoiRegionalizer(seeds=au_seeds_gdf)
au_result_gdf = vr.transform(gdf=au_gdf)
Generating spherical polygons: 0%| | 0/81 [00:00<?, ?it/s]
Generating spherical polygons: 6%|█████████ | 5/81 [00:00<00:01, 49.00it/s]
Generating spherical polygons: 12%|█████████████████▉ | 10/81 [00:00<00:02, 31.19it/s]
Generating spherical polygons: 17%|█████████████████████████ | 14/81 [00:00<00:02, 31.75it/s]
Generating spherical polygons: 25%|███████████████████████████████████▊ | 20/81 [00:00<00:01, 35.42it/s]
Generating spherical polygons: 30%|██████████████████████████████████████████▉ | 24/81 [00:00<00:01, 36.32it/s]
Generating spherical polygons: 42%|████████████████████████████████████████████████████████████▊ | 34/81 [00:01<00:01, 31.80it/s]
Generating spherical polygons: 58%|████████████████████████████████████████████████████████████████████████████████████▏ | 47/81 [00:01<00:00, 43.25it/s]
Generating spherical polygons: 65%|██████████████████████████████████████████████████████████████████████████████████████████████▉ | 53/81 [00:01<00:00, 46.33it/s]
Generating spherical polygons: 81%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ | 66/81 [00:01<00:00, 45.25it/s]
Generating spherical polygons: 88%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ | 71/81 [00:02<00:00, 28.79it/s]
Generating spherical polygons: 99%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ | 80/81 [00:02<00:00, 31.02it/s]
Generating spherical polygons: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 81/81 [00:02<00:00, 35.19it/s]
Interpolating edges: 0%| | 0/300 [00:00<?, ?it/s]
Interpolating edges: 0%|▌ | 1/300 [00:00<01:58, 2.53it/s]
Interpolating edges: 31%|███████████████████████████████████████████████▉ | 94/300 [00:00<00:00, 248.92it/s]
Interpolating edges: 60%|███████████████████████████████████████████████████████████████████████████████████████████▏ | 180/300 [00:00<00:00, 416.91it/s]
Interpolating edges: 90%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▊ | 270/300 [00:00<00:00, 552.98it/s]
Interpolating edges: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 300/300 [00:00<00:00, 401.14it/s]
Generating polygons: 0%| | 0/81 [00:00<?, ?it/s]
Generating polygons: 25%|██████████████████████████████████████ | 20/81 [00:00<00:00, 178.10it/s]
Generating polygons: 47%|████████████████████████████████████████████████████████████████████████▏ | 38/81 [00:00<00:00, 155.27it/s]
Generating polygons: 88%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▉ | 71/81 [00:00<00:00, 189.52it/s]
Generating polygons: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 81/81 [00:00<00:00, 189.01it/s]
In [17]:
Copied!
folium_map = plot_regions(au_result_gdf, tiles_style="CartoDB positron")
au_seeds_gdf.explore(
m=folium_map,
style_kwds=dict(color="#444", opacity=1, fillColor="#f2f2f2", fillOpacity=1),
marker_kwds=dict(radius=3),
)
folium_map = plot_regions(au_result_gdf, tiles_style="CartoDB positron")
au_seeds_gdf.explore(
m=folium_map,
style_kwds=dict(color="#444", opacity=1, fillColor="#f2f2f2", fillOpacity=1),
marker_kwds=dict(radius=3),
)
Out[17]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [18]:
Copied!
neighbourhood = AdjacencyNeighbourhood(regions_gdf=au_result_gdf)
neighbourhood = AdjacencyNeighbourhood(regions_gdf=au_result_gdf)
Nearest neighbours¶
In [19]:
Copied!
region_id = 0
neighbours = neighbourhood.get_neighbours(region_id)
neighbours
region_id = 0
neighbours = neighbourhood.get_neighbours(region_id)
neighbours
Out[19]:
{5, 7, 14, 34, 53, 69, 78}
In [20]:
Copied!
plot_neighbours(au_result_gdf, region_id, neighbours)
plot_neighbours(au_result_gdf, region_id, neighbours)
Out[20]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Neighbours at a distance¶
In [21]:
Copied!
region_id = 0
neighbours = neighbourhood.get_neighbours_at_distance(region_id, 3)
neighbours
region_id = 0
neighbours = neighbourhood.get_neighbours_at_distance(region_id, 3)
neighbours
Out[21]:
{2, 3, 15, 16, 27, 28, 37, 39, 52, 73, 74, 75, 76, 80}
In [22]:
Copied!
plot_neighbours(au_result_gdf, region_id, neighbours)
plot_neighbours(au_result_gdf, region_id, neighbours)
Out[22]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Plotting all neighbourhood¶
In [23]:
Copied!
region_id = 0
plot_all_neighbourhood(au_result_gdf, region_id, neighbourhood)
region_id = 0
plot_all_neighbourhood(au_result_gdf, region_id, neighbourhood)
Out[23]:
Make this Notebook Trusted to load map: File -> Trust Notebook