Access to Hospitals in Siaya County- Number of Hospitals Accessible within 25 Minutes from population point in Siaya
NOTE: Points represent population counts in 500m hexagons covering Siaya County
#Map of accessiblity to hospitals
join.explore(column="access_Hospitals", scheme='natural_breaks',cmap="plasma")
Hospitals in Siaya Source: Open Streets Maps
# Map of hospitals in Siaya
Hospitals.explore()
***Population distribution in Siaya County ***
500 meter hexagon cnetroids ; Population count in 500 meter hexagon
# Population distribution in Siaya
origins.explore(column='Population', scheme='natural_breaks',cmap="plasma")
<frozen importlib._bootstrap>:914: ImportWarning: _PyDrive2ImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _PyDriveImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _GenerativeAIImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _OpenCVImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: APICoreClientInfoImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _BokehImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _AltairImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _PyDrive2ImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _PyDriveImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _GenerativeAIImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _OpenCVImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: APICoreClientInfoImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _BokehImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _AltairImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _PyDrive2ImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _PyDriveImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _GenerativeAIImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _OpenCVImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: APICoreClientInfoImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _BokehImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _AltairImportHook.find_spec() not found; falling back to find_module()
<frozen importlib._bootstrap>:914: ImportWarning: _PyDrive2ImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _PyDriveImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _GenerativeAIImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _OpenCVImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: APICoreClientInfoImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _BokehImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _AltairImportHook.find_spec() not found; falling back to find_module()
Accessibility Modelling
Using the R5Py library to calculate the travel time matrix and analyze the accessibility of urban amenities The R5Py library, is a Python wrapper for the R5 routing engine. R5 is a multimodal routing engine that can be used to calculate travel times between locations in a city using different modes of transport, such as walking, cycling, and public transport. It is open-source, efficient and use real-time data and OpenStreetMap to provide accurate travel time estimates.
R5Py calculates the travel time matrix between origins and destinations.
Step 1: Install and import packages¶
# Install the packages used in the first part of the tutorial
!pip install networkx
!pip install osmnx
!pip install rasterio
Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (3.3) Collecting osmnx Downloading osmnx-1.9.4-py3-none-any.whl.metadata (4.9 kB) Requirement already satisfied: geopandas<0.15,>=0.12 in /usr/local/lib/python3.10/dist-packages (from osmnx) (0.14.4) Requirement already satisfied: networkx<3.4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from osmnx) (3.3) Requirement already satisfied: numpy<1.27,>=1.20 in /usr/local/lib/python3.10/dist-packages (from osmnx) (1.26.4) Requirement already satisfied: pandas<2.3,>=1.1 in /usr/local/lib/python3.10/dist-packages (from osmnx) (2.1.4) Requirement already satisfied: requests<2.33,>=2.27 in /usr/local/lib/python3.10/dist-packages (from osmnx) (2.32.3) Requirement already satisfied: shapely<2.1,>=2.0 in /usr/local/lib/python3.10/dist-packages (from osmnx) (2.0.6) Requirement already satisfied: fiona>=1.8.21 in /usr/local/lib/python3.10/dist-packages (from geopandas<0.15,>=0.12->osmnx) (1.9.6) Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from geopandas<0.15,>=0.12->osmnx) (24.1) Requirement already satisfied: pyproj>=3.3.0 in /usr/local/lib/python3.10/dist-packages (from geopandas<0.15,>=0.12->osmnx) (3.6.1) Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas<2.3,>=1.1->osmnx) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas<2.3,>=1.1->osmnx) (2024.1) Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas<2.3,>=1.1->osmnx) (2024.1) Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<2.33,>=2.27->osmnx) (3.3.2) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<2.33,>=2.27->osmnx) (3.8) Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<2.33,>=2.27->osmnx) (2.0.7) Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<2.33,>=2.27->osmnx) (2024.7.4) Requirement already satisfied: attrs>=19.2.0 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.21->geopandas<0.15,>=0.12->osmnx) (24.2.0) Requirement already satisfied: click~=8.0 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.21->geopandas<0.15,>=0.12->osmnx) (8.1.7) Requirement already satisfied: click-plugins>=1.0 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.21->geopandas<0.15,>=0.12->osmnx) (1.1.1) Requirement already satisfied: cligj>=0.5 in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.21->geopandas<0.15,>=0.12->osmnx) (0.7.2) Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from fiona>=1.8.21->geopandas<0.15,>=0.12->osmnx) (1.16.0) Downloading osmnx-1.9.4-py3-none-any.whl (107 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 107.5/107.5 kB 2.1 MB/s eta 0:00:00 Installing collected packages: osmnx Successfully installed osmnx-1.9.4 Collecting rasterio Downloading rasterio-1.3.10-cp310-cp310-manylinux2014_x86_64.whl.metadata (14 kB) Collecting affine (from rasterio) Downloading affine-2.4.0-py3-none-any.whl.metadata (4.0 kB) Requirement already satisfied: attrs in /usr/local/lib/python3.10/dist-packages (from rasterio) (24.2.0) Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from rasterio) (2024.7.4) Requirement already satisfied: click>=4.0 in /usr/local/lib/python3.10/dist-packages (from rasterio) (8.1.7) Requirement already satisfied: cligj>=0.5 in /usr/local/lib/python3.10/dist-packages (from rasterio) (0.7.2) Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from rasterio) (1.26.4) Collecting snuggs>=1.4.1 (from rasterio) Downloading snuggs-1.4.7-py3-none-any.whl.metadata (3.4 kB) Requirement already satisfied: click-plugins in /usr/local/lib/python3.10/dist-packages (from rasterio) (1.1.1) Requirement already satisfied: setuptools in /usr/local/lib/python3.10/dist-packages (from rasterio) (71.0.4) Requirement already satisfied: pyparsing>=2.1.6 in /usr/local/lib/python3.10/dist-packages (from snuggs>=1.4.1->rasterio) (3.1.4) Downloading rasterio-1.3.10-cp310-cp310-manylinux2014_x86_64.whl (21.5 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 21.5/21.5 MB 41.0 MB/s eta 0:00:00 Downloading snuggs-1.4.7-py3-none-any.whl (5.4 kB) Downloading affine-2.4.0-py3-none-any.whl (15 kB) Installing collected packages: snuggs, affine, rasterio Successfully installed affine-2.4.0 rasterio-1.3.10 snuggs-1.4.7
# Install the packages used in the third part of the tutorial
!pip install r5py
!pip install mapclassify
!pip install folium
Collecting r5py Downloading r5py-0.1.2-py3-none-any.whl.metadata (10 kB) Collecting ConfigArgParse (from r5py) Downloading ConfigArgParse-1.7-py3-none-any.whl.metadata (23 kB) Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from r5py) (3.15.4) Requirement already satisfied: fiona in /usr/local/lib/python3.10/dist-packages (from r5py) (1.9.6) Requirement already satisfied: geopandas in /usr/local/lib/python3.10/dist-packages (from r5py) (0.14.4) Requirement already satisfied: importlib-resources in /usr/local/lib/python3.10/dist-packages (from r5py) (6.4.4) Requirement already satisfied: joblib in /usr/local/lib/python3.10/dist-packages (from r5py) (1.4.2) Collecting jpype1 (from r5py) Downloading JPype1-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB) Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from r5py) (1.26.4) Requirement already satisfied: pandas>=2.1.0 in /usr/local/lib/python3.10/dist-packages (from r5py) (2.1.4) Requirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from r5py) (5.9.5) Requirement already satisfied: pyproj in /usr/local/lib/python3.10/dist-packages (from r5py) (3.6.1) Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from r5py) (2.32.3) Requirement already satisfied: shapely>=2.0 in /usr/local/lib/python3.10/dist-packages (from r5py) (2.0.6) Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2024.1) Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2024.1) Requirement already satisfied: attrs>=19.2.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (24.2.0) Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (2024.7.4) Requirement already satisfied: click~=8.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (8.1.7) Requirement already satisfied: click-plugins>=1.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (1.1.1) Requirement already satisfied: cligj>=0.5 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (0.7.2) Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (1.16.0) Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from geopandas->r5py) (24.1) Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (3.3.2) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (3.8) Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (2.0.7) Downloading r5py-0.1.2-py3-none-any.whl (51 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 51.7/51.7 kB 2.5 MB/s eta 0:00:00 Downloading ConfigArgParse-1.7-py3-none-any.whl (25 kB) Downloading JPype1-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (488 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 488.6/488.6 kB 12.7 MB/s eta 0:00:00 Installing collected packages: jpype1, ConfigArgParse, r5py Successfully installed ConfigArgParse-1.7 jpype1-1.5.0 r5py-0.1.2 Collecting mapclassify Downloading mapclassify-2.8.0-py3-none-any.whl.metadata (2.8 kB) Requirement already satisfied: networkx>=2.7 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (3.3) Requirement already satisfied: numpy>=1.23 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.26.4) Requirement already satisfied: pandas!=1.5.0,>=1.4 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (2.1.4) Requirement already satisfied: scikit-learn>=1.0 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.3.2) Requirement already satisfied: scipy>=1.8 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.13.1) Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2024.1) Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2024.1) Requirement already satisfied: joblib>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from scikit-learn>=1.0->mapclassify) (1.4.2) Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn>=1.0->mapclassify) (3.5.0) Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.2->pandas!=1.5.0,>=1.4->mapclassify) (1.16.0) Downloading mapclassify-2.8.0-py3-none-any.whl (58 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.9/58.9 kB 2.6 MB/s eta 0:00:00 Installing collected packages: mapclassify Successfully installed mapclassify-2.8.0 Requirement already satisfied: folium in /usr/local/lib/python3.10/dist-packages (0.17.0) Requirement already satisfied: branca>=0.6.0 in /usr/local/lib/python3.10/dist-packages (from folium) (0.7.2) Requirement already satisfied: jinja2>=2.9 in /usr/local/lib/python3.10/dist-packages (from folium) (3.1.4) Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from folium) (1.26.4) Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from folium) (2.32.3) Requirement already satisfied: xyzservices in /usr/local/lib/python3.10/dist-packages (from folium) (2024.6.0) Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2>=2.9->folium) (2.1.5) Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (3.3.2) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (3.8) Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (2.0.7) Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (2024.7.4)
Step 2: Install Java 21¶
#Java 21
!java -version
!apt-get update
!apt-get install -y openjdk-21-jdk
import os
os.environ['JAVA_HOME'] = '/usr/lib/jvm/java-21-openjdk-amd64'
os.environ['PATH'] = f"{os.environ['JAVA_HOME']}/bin:{os.environ['PATH']}"
openjdk version "11.0.24" 2024-07-16 OpenJDK Runtime Environment (build 11.0.24+8-post-Ubuntu-1ubuntu322.04) OpenJDK 64-Bit Server VM (build 11.0.24+8-post-Ubuntu-1ubuntu322.04, mixed mode, sharing) Get:1 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64 InRelease [1,581 B] Get:2 https://cloud.r-project.org/bin/linux/ubuntu jammy-cran40/ InRelease [3,626 B] Get:3 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64 Packages [962 kB] Get:4 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB] Hit:5 http://archive.ubuntu.com/ubuntu jammy InRelease Get:6 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB] Ign:7 https://r2u.stat.illinois.edu/ubuntu jammy InRelease Get:8 https://r2u.stat.illinois.edu/ubuntu jammy Release [5,713 B] Get:9 https://r2u.stat.illinois.edu/ubuntu jammy Release.gpg [793 B] Hit:10 https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy InRelease Get:11 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [1,145 kB] Hit:12 http://archive.ubuntu.com/ubuntu jammy-backports InRelease Get:13 https://r2u.stat.illinois.edu/ubuntu jammy/main all Packages [8,264 kB] Get:14 https://ppa.launchpadcontent.net/graphics-drivers/ppa/ubuntu jammy InRelease [24.3 kB] Get:15 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [1,435 kB] Hit:16 https://ppa.launchpadcontent.net/ubuntugis/ppa/ubuntu jammy InRelease Get:17 https://ppa.launchpadcontent.net/graphics-drivers/ppa/ubuntu jammy/main amd64 Packages [53.3 kB] Get:18 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [2,221 kB] Get:19 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [2,499 kB] Get:20 https://r2u.stat.illinois.edu/ubuntu jammy/main amd64 Packages [2,561 kB] Fetched 19.4 MB in 4s (4,935 kB/s) Reading package lists... Done W: Skipping acquire of configured file 'main/source/Sources' as repository 'https://r2u.stat.illinois.edu/ubuntu jammy InRelease' does not seem to provide it (sources.list entry misspelt?) Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: fonts-dejavu-core fonts-dejavu-extra libatk-wrapper-java libatk-wrapper-java-jni libfontenc1 libice-dev libsm-dev libxkbfile1 libxt-dev libxtst6 libxxf86dga1 openjdk-21-jdk-headless openjdk-21-jre openjdk-21-jre-headless x11-utils Suggested packages: libice-doc libsm-doc libxt-doc openjdk-21-demo openjdk-21-source visualvm libnss-mdns fonts-ipafont-gothic fonts-ipafont-mincho fonts-wqy-microhei | fonts-wqy-zenhei fonts-indic mesa-utils The following NEW packages will be installed: fonts-dejavu-core fonts-dejavu-extra libatk-wrapper-java libatk-wrapper-java-jni libfontenc1 libice-dev libsm-dev libxkbfile1 libxt-dev libxtst6 libxxf86dga1 openjdk-21-jdk openjdk-21-jdk-headless openjdk-21-jre openjdk-21-jre-headless x11-utils 0 upgraded, 16 newly installed, 0 to remove and 50 not upgraded. Need to get 135 MB of archives. After this operation, 314 MB of additional disk space will be used. Get:1 http://archive.ubuntu.com/ubuntu jammy/main amd64 fonts-dejavu-core all 2.37-2build1 [1,041 kB] Get:2 http://archive.ubuntu.com/ubuntu jammy/main amd64 fonts-dejavu-extra all 2.37-2build1 [2,041 kB] Get:3 http://archive.ubuntu.com/ubuntu jammy/main amd64 libfontenc1 amd64 1:1.1.4-1build3 [14.7 kB] Get:4 http://archive.ubuntu.com/ubuntu jammy/main amd64 libxkbfile1 amd64 1:1.1.0-1build3 [71.8 kB] Get:5 http://archive.ubuntu.com/ubuntu jammy/main amd64 libxtst6 amd64 2:1.2.3-1build4 [13.4 kB] Get:6 http://archive.ubuntu.com/ubuntu jammy/main amd64 libxxf86dga1 amd64 2:1.1.5-0ubuntu3 [12.6 kB] Get:7 http://archive.ubuntu.com/ubuntu jammy/main amd64 x11-utils amd64 7.7+5build2 [206 kB] Get:8 http://archive.ubuntu.com/ubuntu jammy/main amd64 libatk-wrapper-java all 0.38.0-5build1 [53.1 kB] Get:9 http://archive.ubuntu.com/ubuntu jammy/main amd64 libatk-wrapper-java-jni amd64 0.38.0-5build1 [49.0 kB] Get:10 http://archive.ubuntu.com/ubuntu jammy/main amd64 libice-dev amd64 2:1.0.10-1build2 [51.4 kB] Get:11 http://archive.ubuntu.com/ubuntu jammy/main amd64 libsm-dev amd64 2:1.2.3-1build2 [18.1 kB] Get:12 http://archive.ubuntu.com/ubuntu jammy/main amd64 libxt-dev amd64 1:1.2.1-1 [396 kB] Get:13 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 openjdk-21-jre-headless amd64 21.0.4+7-1ubuntu2~22.04 [47.0 MB] Get:14 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 openjdk-21-jre amd64 21.0.4+7-1ubuntu2~22.04 [232 kB] Get:15 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 openjdk-21-jdk-headless amd64 21.0.4+7-1ubuntu2~22.04 [82.5 MB] Get:16 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 openjdk-21-jdk amd64 21.0.4+7-1ubuntu2~22.04 [1,634 kB] Fetched 135 MB in 13s (10.6 MB/s) Selecting previously unselected package fonts-dejavu-core. (Reading database ... 123597 files and directories currently installed.) Preparing to unpack .../00-fonts-dejavu-core_2.37-2build1_all.deb ... Unpacking fonts-dejavu-core (2.37-2build1) ... Selecting previously unselected package fonts-dejavu-extra. Preparing to unpack .../01-fonts-dejavu-extra_2.37-2build1_all.deb ... Unpacking fonts-dejavu-extra (2.37-2build1) ... Selecting previously unselected package libfontenc1:amd64. Preparing to unpack .../02-libfontenc1_1%3a1.1.4-1build3_amd64.deb ... Unpacking libfontenc1:amd64 (1:1.1.4-1build3) ... Selecting previously unselected package libxkbfile1:amd64. Preparing to unpack .../03-libxkbfile1_1%3a1.1.0-1build3_amd64.deb ... Unpacking libxkbfile1:amd64 (1:1.1.0-1build3) ... Selecting previously unselected package libxtst6:amd64. Preparing to unpack .../04-libxtst6_2%3a1.2.3-1build4_amd64.deb ... Unpacking libxtst6:amd64 (2:1.2.3-1build4) ... Selecting previously unselected package libxxf86dga1:amd64. Preparing to unpack .../05-libxxf86dga1_2%3a1.1.5-0ubuntu3_amd64.deb ... Unpacking libxxf86dga1:amd64 (2:1.1.5-0ubuntu3) ... Selecting previously unselected package x11-utils. Preparing to unpack .../06-x11-utils_7.7+5build2_amd64.deb ... Unpacking x11-utils (7.7+5build2) ... Selecting previously unselected package libatk-wrapper-java. Preparing to unpack .../07-libatk-wrapper-java_0.38.0-5build1_all.deb ... Unpacking libatk-wrapper-java (0.38.0-5build1) ... Selecting previously unselected package libatk-wrapper-java-jni:amd64. Preparing to unpack .../08-libatk-wrapper-java-jni_0.38.0-5build1_amd64.deb ... Unpacking libatk-wrapper-java-jni:amd64 (0.38.0-5build1) ... Selecting previously unselected package libice-dev:amd64. Preparing to unpack .../09-libice-dev_2%3a1.0.10-1build2_amd64.deb ... Unpacking libice-dev:amd64 (2:1.0.10-1build2) ... Selecting previously unselected package libsm-dev:amd64. Preparing to unpack .../10-libsm-dev_2%3a1.2.3-1build2_amd64.deb ... Unpacking libsm-dev:amd64 (2:1.2.3-1build2) ... Selecting previously unselected package libxt-dev:amd64. Preparing to unpack .../11-libxt-dev_1%3a1.2.1-1_amd64.deb ... Unpacking libxt-dev:amd64 (1:1.2.1-1) ... Selecting previously unselected package openjdk-21-jre-headless:amd64. Preparing to unpack .../12-openjdk-21-jre-headless_21.0.4+7-1ubuntu2~22.04_amd64.deb ... Unpacking openjdk-21-jre-headless:amd64 (21.0.4+7-1ubuntu2~22.04) ... Selecting previously unselected package openjdk-21-jre:amd64. Preparing to unpack .../13-openjdk-21-jre_21.0.4+7-1ubuntu2~22.04_amd64.deb ... Unpacking openjdk-21-jre:amd64 (21.0.4+7-1ubuntu2~22.04) ... Selecting previously unselected package openjdk-21-jdk-headless:amd64. Preparing to unpack .../14-openjdk-21-jdk-headless_21.0.4+7-1ubuntu2~22.04_amd64.deb ... Unpacking openjdk-21-jdk-headless:amd64 (21.0.4+7-1ubuntu2~22.04) ... Selecting previously unselected package openjdk-21-jdk:amd64. Preparing to unpack .../15-openjdk-21-jdk_21.0.4+7-1ubuntu2~22.04_amd64.deb ... Unpacking openjdk-21-jdk:amd64 (21.0.4+7-1ubuntu2~22.04) ... Setting up openjdk-21-jre-headless:amd64 (21.0.4+7-1ubuntu2~22.04) ... update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/java to provide /usr/bin/java (java) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jpackage to provide /usr/bin/jpackage (jpackage) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/keytool to provide /usr/bin/keytool (keytool) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/rmiregistry to provide /usr/bin/rmiregistry (rmiregistry) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/lib/jexec to provide /usr/bin/jexec (jexec) in auto mode Setting up libice-dev:amd64 (2:1.0.10-1build2) ... Setting up libsm-dev:amd64 (2:1.2.3-1build2) ... Setting up libxtst6:amd64 (2:1.2.3-1build4) ... Setting up libxxf86dga1:amd64 (2:1.1.5-0ubuntu3) ... Setting up openjdk-21-jre:amd64 (21.0.4+7-1ubuntu2~22.04) ... Setting up libfontenc1:amd64 (1:1.1.4-1build3) ... Setting up libxt-dev:amd64 (1:1.2.1-1) ... Setting up fonts-dejavu-core (2.37-2build1) ... Setting up fonts-dejavu-extra (2.37-2build1) ... Setting up libxkbfile1:amd64 (1:1.1.0-1build3) ... Setting up openjdk-21-jdk-headless:amd64 (21.0.4+7-1ubuntu2~22.04) ... update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jar to provide /usr/bin/jar (jar) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jarsigner to provide /usr/bin/jarsigner (jarsigner) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/javac to provide /usr/bin/javac (javac) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/javadoc to provide /usr/bin/javadoc (javadoc) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/javap to provide /usr/bin/javap (javap) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jcmd to provide /usr/bin/jcmd (jcmd) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jdb to provide /usr/bin/jdb (jdb) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jdeprscan to provide /usr/bin/jdeprscan (jdeprscan) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jdeps to provide /usr/bin/jdeps (jdeps) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jfr to provide /usr/bin/jfr (jfr) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jimage to provide /usr/bin/jimage (jimage) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jinfo to provide /usr/bin/jinfo (jinfo) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jlink to provide /usr/bin/jlink (jlink) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jmap to provide /usr/bin/jmap (jmap) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jmod to provide /usr/bin/jmod (jmod) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jps to provide /usr/bin/jps (jps) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jrunscript to provide /usr/bin/jrunscript (jrunscript) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jshell to provide /usr/bin/jshell (jshell) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jstack to provide /usr/bin/jstack (jstack) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jstat to provide /usr/bin/jstat (jstat) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jstatd to provide /usr/bin/jstatd (jstatd) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jwebserver to provide /usr/bin/jwebserver (jwebserver) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/serialver to provide /usr/bin/serialver (serialver) in auto mode update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jhsdb to provide /usr/bin/jhsdb (jhsdb) in auto mode Setting up openjdk-21-jdk:amd64 (21.0.4+7-1ubuntu2~22.04) ... update-alternatives: using /usr/lib/jvm/java-21-openjdk-amd64/bin/jconsole to provide /usr/bin/jconsole (jconsole) in auto mode Setting up x11-utils (7.7+5build2) ... Setting up libatk-wrapper-java (0.38.0-5build1) ... Setting up libatk-wrapper-java-jni:amd64 (0.38.0-5build1) ... Processing triggers for hicolor-icon-theme (0.17-2) ... Processing triggers for libc-bin (2.35-0ubuntu3.4) ... /sbin/ldconfig.real: /usr/local/lib/libur_loader.so.0 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libtbbmalloc_proxy.so.2 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libtbbbind.so.3 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libtbbbind_2_0.so.3 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libur_adapter_level_zero.so.0 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libtbbmalloc.so.2 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libtbb.so.12 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libur_adapter_opencl.so.0 is not a symbolic link /sbin/ldconfig.real: /usr/local/lib/libtbbbind_2_5.so.3 is not a symbolic link Processing triggers for man-db (2.10.2-1) ... Processing triggers for fontconfig (2.13.1-4.2ubuntu5) ...
Step 3: Import Libraries¶
#### Import the necessary libraries ####
# R5Py for travel time matrix computation
from r5py import TransportNetwork, TravelTimeMatrixComputer
# GeoPandas for spatial data manipulation
import geopandas as gpd
import pandas as pd
# General library
from matplotlib import pyplot as plt
from datetime import datetime, timedelta
import networkx as nx
import osmnx as ox
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import geopandas as gpd
# from osgeo import gdal
Step 4: Import Warnings¶
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning, module="pandas.core.frame")
Step 5: Get the Siaya County Boundary¶
import osmnx as ox
import geopandas as gpd
import matplotlib.pyplot as plt
# Define the place name
place_name = "Siaya County, Kenya"
# Get the boundary polygon of Siaya County
gdf = ox.geocode_to_gdf(place_name)
# Display the boundary GeoDataFrame
print(gdf)
# Plot the boundary polygon
gdf.plot()
plt.title("Boundary of Siaya County")
plt.show()
geometry bbox_north bbox_south \ 0 POLYGON ((33.94912 -0.33974, 34.21235 -0.34072... 0.311022 -0.431292 bbox_east bbox_west place_id osm_type osm_id lat lon \ 0 34.559942 33.949123 368231981 relation 3486291 -0.060401 34.200135 class type place_rank importance addresstype name \ 0 boundary administrative 8 0.406682 state Siaya County display_name 0 Siaya County, Nyanza, Kenya
import osmnx as ox
# Download Siaya County boundary using OSM
siaya_boundary = ox.geocode_to_gdf('Siaya County, Kenya')
# Save it to a shapefile (optional)
siaya_boundary.to_file('siaya_boundary.shp')
<ipython-input-7-97186e1fa29b>:7: UserWarning: Column names longer than 10 characters will be truncated when saved to ESRI Shapefile. siaya_boundary.to_file('siaya_boundary.shp') WARNING:fiona._env:Normalized/laundered field name: 'addresstype' to 'addresstyp' WARNING:fiona._env:Normalized/laundered field name: 'display_name' to 'display_na'
import geopandas as gpd
# Load the shapefile
shapefile_path = "siaya_boundary.shp"
gdf = gpd.read_file(shapefile_path)
# Convert the GeoDataFrame to GeoJSON
geojson_path = "siaya_boundary.geojson"
gdf.to_file(geojson_path, driver='GeoJSON')
print(f"Shapefile successfully converted to GeoJSON and saved at: {geojson_path}")
Shapefile successfully converted to GeoJSON and saved at: siaya_boundary.geojson
Step 6 Acquire Spatial Data¶
# Download Hospitals from OSM
# Define the location of interest
place_name = "Siaya County"
# Define the tags for hospitals
#hospital_tags = {'amenity': 'hospital', 'geometry':'point'}
# Use the new `features_from_place` function instead of `geometries_from_place`
#hospitals = ox.features_from_place(place_name, tags=hospital_tags)
hospitals = ox.features_from_place(place_name, tags={'amenity':'hospital', 'geometry':'point'})
# Ensure the geometry column is properly set
if 'geometry' not in hospitals.columns or hospitals.geometry.is_empty.all():
raise ValueError("The 'geometry' column does not contain valid geometries.")
# Function to clean the GeoDataFrame
def clean_geodataframe(gdf):
# Drop columns with unsupported data types
for column in gdf.columns:
if gdf[column].apply(lambda x: isinstance(x, (list, dict, tuple))).any():
gdf = gdf.drop(columns=[column])
# Drop rows with invalid geometries
gdf = gdf.dropna(subset=['geometry'])
gdf = gdf[gdf.geometry.notna()]
return gdf
hospitals_cleaned = clean_geodataframe(hospitals)
# Save the cleaned hospitals data to a GeoJSON file
hospitals_cleaned.to_file("hospitalsN.geojson", driver="GeoJSON")
##Covert polygons to points
import json
# Load GeoJSON data from a file (replace with your actual GeoJSON file path)
geojson_file_path = "hospitalsN.geojson"
with open(geojson_file_path, "r") as infile:
geojson_data = json.load(infile)
# Create an empty list to store the points
points = []
# Iterate through each feature in the GeoJSON data
for feature in geojson_data["features"]:
if feature["geometry"]["type"] == "Polygon":
# Calculate the centroid of the polygon
coordinates = feature["geometry"]["coordinates"][0] # Assuming the first set of coordinates is the outer ring
lon = sum(coord[0] for coord in coordinates) / len(coordinates)
lat = sum(coord[1] for coord in coordinates) / len(coordinates)
# Create a new point feature with the same attributes as the original polygon
point_feature = {
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [lon, lat]},
"properties": feature.get("properties", {}),
}
points.append(point_feature)
elif feature["geometry"]["type"] == "Point":
# Retain existing point features
points.append(feature)
# Create a new GeoJSON object with the points
points_geojson = {"type": "FeatureCollection", "features": points}
# Save the points GeoJSON to a file (optional)
with open("points2.geojson", "w") as outfile:
json.dump(points_geojson, outfile)
Hospitals = gpd.read_file('points2.geojson')
Hospitals.head()
<frozen importlib._bootstrap>:914: ImportWarning: _PyDrive2ImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _PyDriveImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _GenerativeAIImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _OpenCVImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: APICoreClientInfoImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _BokehImportHook.find_spec() not found; falling back to find_module() <frozen importlib._bootstrap>:914: ImportWarning: _AltairImportHook.find_spec() not found; falling back to find_module()
element_type | osmid | amenity | name | operator | emergency | healthcare | healthcare:speciality | building | addr:city | addr:postcode | operator:type | leisure | geometry | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | node | 1419020606 | hospital | St Paul's Health Centre | None | yes | None | None | None | None | None | None | None | POINT (34.29362 0.16300) |
1 | node | 1850405064 | hospital | None | None | None | hospital | None | None | None | None | None | None | POINT (34.36263 0.15645) |
2 | node | 11693537898 | hospital | Yala Level 4 Hospital | None | None | hospital | None | None | None | None | None | None | POINT (34.53782 0.10127) |
3 | way | 129746965 | hospital | St Paul PSC Section | None | None | None | None | None | None | None | None | None | POINT (34.29335 0.16304) |
4 | way | 129856950 | hospital | Ambira Sub District Hospital | None | yes | None | None | None | None | None | None | None | POINT (34.28540 0.18108) |
##Change osmid to id
Hospitals = Hospitals.rename(columns={'osmid': 'id'})
#Retain name, geometry and ID columns
columns_to_retain = ['id', 'geometry','name']
Hospitals = Hospitals[columns_to_retain]
Hospitals.head()
id | geometry | name | |
---|---|---|---|
0 | 1419020606 | POINT (34.29362 0.16300) | St Paul's Health Centre |
1 | 1850405064 | POINT (34.36263 0.15645) | None |
2 | 11693537898 | POINT (34.53782 0.10127) | Yala Level 4 Hospital |
3 | 129746965 | POINT (34.29335 0.16304) | St Paul PSC Section |
4 | 129856950 | POINT (34.28540 0.18108) | Ambira Sub District Hospital |
##Check for duplication of features when polygons were converted to points.
#In the case of hospitals in Siaya, some facilities had double represntation e.g Ambira Sub District Hospital was represented as two points
# You can verify through visual inspection in QGIS
#Remove duplicates
import json
# Load the GeoJSON file
with open('points2.geojson', 'r') as f:
geojson_data = json.load(f)
# Define the list of IDs to remove
ids_to_remove = [772387134, 774523118, 180331572]
# Get the features from the GeoJSON data
features = geojson_data['features']
# Remove the features with the matching IDs
features = [feature for feature in features if feature['properties']['osmid'] not in ids_to_remove]
# Update the GeoJSON data with the modified features
geojson_data['features'] = features
# Write the updated GeoJSON data to a new file
with open('points_cleaned.geojson', 'w') as f:
json.dump(geojson_data, f)
##Get grid or other geography to represent origins
##hexagon grid of created in QGIS at 500meteres aggregating the WorldPop grid centroids from 100meters
origins = gpd.read_file('siaya_centroids_population.geojson')
origins.head()
Population | geometry | |
---|---|---|
0 | 9.754832 | POINT (34.29512 -0.40250) |
1 | 8.343940 | POINT (34.30346 -0.40250) |
2 | 5.247587 | POINT (34.28678 -0.40250) |
3 | 6.275999 | POINT (34.29095 -0.40250) |
4 | 5.481225 | POINT (34.28262 -0.39833) |
import geopandas as gpd
# Load the origins dataset
origins = gpd.read_file('siaya_centroids_population.geojson')
# Add the 'id' column with unique identifiers
origins['id'] = range(1, len(origins) + 1)
# Add the 'Location' column with random names
origins['Location'] = ['Location' + str(i) for i in range(1, len(origins) + 1)]
origins.head()
Population | geometry | id | Location | |
---|---|---|---|---|
0 | 9.754832 | POINT (34.29512 -0.40250) | 1 | Location1 |
1 | 8.343940 | POINT (34.30346 -0.40250) | 2 | Location2 |
2 | 5.247587 | POINT (34.28678 -0.40250) | 3 | Location3 |
3 | 6.275999 | POINT (34.29095 -0.40250) | 4 | Location4 |
4 | 5.481225 | POINT (34.28262 -0.39833) | 5 | Location5 |
# Import spatial boundaries of Siaya for context; they are obtained from ONS as open geo-boundary data
ox_bound = gpd.read_file('siaya_boundary.geojson').to_crs(epsg=4326)
Time matrix and accessibility¶
To start with the accessibility analysis, we would like to make the simplist case: How long it would take from one certain place to travel to another?
###### Create a TransportNetwork object in R5Pyusing the OSM data ######
# This provides a basis for analysis in the entire third section
#Get osm_pbf from 'extract.bbbike.org'
transport_network = TransportNetwork(
osm_pbf='Siaya.osm.pbf', # Path to the OSM PBF file
)
# Select one point as origin, you can choose any point in the origins dataset
# Some good example could include:
# 1308 - The city center
# 2058 - Department of Stats Building
# 1319 - Lady Margaret Hall
Ambira = Hospitals.loc[Hospitals['name'] == "Ambira Sub District Hospital"]
# Create a TravelTimeMatrixComputer object using R5Py to calculate travel times
# This is a key step as it will determine the travel times between all pairs of origins and destinations in the network
travel_time_computer_point = TravelTimeMatrixComputer(
transport_network=transport_network,
origins=Ambira,
destinations=origins,
snap_to_network=True,
# Below are some of the travel options that can be tweaked as needed
transport_modes=['WALK', 'TRANSIT', 'CAR'], # Modes of transport to consider, e.g., 'WALK', 'BICYCLE', 'CAR', 'TRANSIT'
# speed_walking=3.6,
)
# For more information on the available options, please refer to the R5Py documentation: https://r5py.readthedocs.io/en/latest/
/usr/local/lib/python3.10/dist-packages/r5py/r5/regional_task.py:227: RuntimeWarning: Departure time 2024-09-02 18:30:42.120076 is outside of the time range covered by currently loaded GTFS data sets. warnings.warn(
# Compute travel times between all origins and destinations;
od_matrix_point = travel_time_computer_point.compute_travel_times()
/usr/local/lib/python3.10/dist-packages/r5py/r5/base_travel_time_matrix_computer.py:150: RuntimeWarning: Some destination points could not be snapped to the street network warnings.warn(
od_matrix_point.head()
# The calculated time_matrix is vey simple: you have the starting id, and its time of travel to any other location (id).
from_id | to_id | travel_time | |
---|---|---|---|
0 | 129856950 | 1 | 78.0 |
1 | 129856950 | 2 | 76.0 |
2 | 129856950 | 3 | 77.0 |
3 | 129856950 | 4 | 78.0 |
4 | 129856950 | 5 | 74.0 |
od_matrix_point['to_id'] = od_matrix_point['to_id'].astype('int64')
join_point = origins.merge(od_matrix_point, left_on='id', right_on='to_id')
join_point.head()
# You can see how the aggregated data look like. A geometry is introduced to spatially plot the accessibility.
Population | geometry | id | Location | from_id | to_id | travel_time | |
---|---|---|---|---|---|---|---|
0 | 9.754832 | POINT (34.29512 -0.40250) | 1 | Location1 | 129856950 | 1 | 78.0 |
1 | 8.343940 | POINT (34.30346 -0.40250) | 2 | Location2 | 129856950 | 2 | 76.0 |
2 | 5.247587 | POINT (34.28678 -0.40250) | 3 | Location3 | 129856950 | 3 | 77.0 |
3 | 6.275999 | POINT (34.29095 -0.40250) | 4 | Location4 | 129856950 | 4 | 78.0 |
4 | 5.481225 | POINT (34.28262 -0.39833) | 5 | Location5 | 129856950 | 5 | 74.0 |
# Build a plot to show the travel times
fig, ax = plt.subplots(figsize=(10,8)) # Adjust size as needed
# Plot the boundary for context
ox_bound.plot(ax=ax, color='none', scheme='natural_breaks', linewidth=1)
join_point.plot(ax=ax,column="travel_time", cmap="cividis_r",scheme = 'natural_breaks', markersize=2,linewidth=1,legend=True,aspect='equal')
Ambira.plot(ax=ax, color='red', markersize=10,legend=True)
ax.set_title("Travel time from selected point to all destinations combining public transport and active travel")
ax.set_axis_off()
/usr/local/lib/python3.10/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above. and should_run_async(code)
Walking
travel_time_computer_point_walk = TravelTimeMatrixComputer(
transport_network=transport_network,
origins=Ambira,
destinations=origins,
snap_to_network=True,
# Below are some of the travel options that can be tweaked as needed
transport_modes=['WALK'], # Modes of transport to consider, e.g., 'WALK', 'BICYCLE', 'CAR', 'TRANSIT'
# speed_walking=3.6,
)
# Compute travel times between all origins and destinations
od_matrix_point_walk = travel_time_computer_point_walk.compute_travel_times()
# Create the combined matrix
join_point = origins.merge(od_matrix_point_walk, left_on="id", right_on="to_id")
join_point.head()
/usr/local/lib/python3.10/dist-packages/r5py/r5/base_travel_time_matrix_computer.py:150: RuntimeWarning: Some destination points could not be snapped to the street network warnings.warn(
Population | geometry | id | Location | from_id | to_id | travel_time | |
---|---|---|---|---|---|---|---|
0 | 9.754832 | POINT (34.29512 -0.40250) | 1 | Location1 | 129856950 | 1 | NaN |
1 | 8.343940 | POINT (34.30346 -0.40250) | 2 | Location2 | 129856950 | 2 | NaN |
2 | 5.247587 | POINT (34.28678 -0.40250) | 3 | Location3 | 129856950 | 3 | NaN |
3 | 6.275999 | POINT (34.29095 -0.40250) | 4 | Location4 | 129856950 | 4 | NaN |
4 | 5.481225 | POINT (34.28262 -0.39833) | 5 | Location5 | 129856950 | 5 | NaN |
join_point.explore(column="travel_time", scheme='natural_breaks',cmap="cividis_r")
# Or, You can use this part to plot the result
fig, ax = plt.subplots(figsize=(10,8)) # Adjust size as needed
# Change the following line to your own variable.
join_point.plot(ax=ax,column="travel_time", cmap="cividis_r",markersize=2,linewidth=1,legend=True)
Ambira.plot(ax=ax, color='red', markersize=10, scheme='natural_breaks', legend=True)
ox_bound.plot(ax=ax, color='none',linewidth=1)
ax.set_title("Travel time from selected point to all destinations with only walking")
ax.set_axis_off()
/usr/local/lib/python3.10/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above. and should_run_async(code)
Opportunities accessible within a certain travel time¶
It is important to understand the accessibility of urban amenities, such as food outlets, schools, and healthcare facilities, to different parts of the city. This information can help urban planners and policymakers identify areas with limited access to essential services and improve the overall accessibility of the city.
Similar case can be made for the accessibility of opportunities, such as jobs and schools.
In this case, we will calculate the number of hopsitals accessible within 25 minutes of sustainable travel (walking, cycling and public transport) from each population grid in the city.
travel_time_computer = TravelTimeMatrixComputer(
transport_network=transport_network,
origins=origins,
destinations=Hospitals, #
#snap_to_network=True,
transport_modes=['WALK','BICYCLE', 'TRANSIT'],
)
/usr/local/lib/python3.10/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above. and should_run_async(code) /usr/local/lib/python3.10/dist-packages/r5py/r5/regional_task.py:227: RuntimeWarning: Departure time 2024-09-02 18:30:42.120076 is outside of the time range covered by currently loaded GTFS data sets. warnings.warn(
od_matrix = travel_time_computer.compute_travel_times()
# Normally we should compute the calculation using colab, but in the beta stage,
# the time it took is too long (40minutes). So we have referred to a pre-calculated matrix
# for the travel time data. They are the same though!
# If you are finding the previous block taking more than 3mins to run, you can
# uncomment the following block to load the pre-calculated matrix.
# od_matrix = pd.read_csv(wd+'results/od_matrix.csv')
time_threshold = 25
# Filter the OD matrix to include only travel times less than or equal to 25 minutes
filtered_matrix = od_matrix[od_matrix['travel_time'] <= time_threshold]
# Count the number of accessible POIs for each population grid
accessible_pois = filtered_matrix.groupby('from_id').size().reset_index(name='access_Hospitals')
# Merge the accessibility information with the origins GeoDataFrame for plotting
join = origins.merge(accessible_pois, left_on="id", right_on="from_id")
# Build a plot to show the accessible opportunities
fig, ax = plt.subplots(figsize=(10,8)) # Adjust size as needed
# Plot the Oxford County boundary for context
ox_bound.plot(ax=ax, color='none', scheme='natural_breaks', linewidth=1)
# Plot the number of accessible food outlets aggregated in the above block
join.plot(ax=ax,column="access_Hospitals", scheme='natural_breaks',cmap="plasma",markersize=2,linewidth=1, legend=True)
ax.set_title(f"Number of Hospitals Accessible Under {time_threshold} Minutes")
ax.set_axis_off()
import geopandas
import shapely
population_grid = geopandas.read_file("SiayaGPKG.gpkg")
print(population_grid.columns)
Index(['VALUE', 'geometry'], dtype='object')
# Install the packages used in the third part of the tutorial
!pip install r5py
!pip install mapclassify
!pip install folium
Collecting r5py Downloading r5py-0.1.2-py3-none-any.whl.metadata (10 kB) Collecting ConfigArgParse (from r5py) Downloading ConfigArgParse-1.7-py3-none-any.whl.metadata (23 kB) Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from r5py) (3.15.4) Requirement already satisfied: fiona in /usr/local/lib/python3.10/dist-packages (from r5py) (1.9.6) Requirement already satisfied: geopandas in /usr/local/lib/python3.10/dist-packages (from r5py) (0.14.4) Requirement already satisfied: importlib-resources in /usr/local/lib/python3.10/dist-packages (from r5py) (6.4.4) Requirement already satisfied: joblib in /usr/local/lib/python3.10/dist-packages (from r5py) (1.4.2) Collecting jpype1 (from r5py) Downloading JPype1-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB) Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from r5py) (1.26.4) Requirement already satisfied: pandas>=2.1.0 in /usr/local/lib/python3.10/dist-packages (from r5py) (2.1.4) Requirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from r5py) (5.9.5) Requirement already satisfied: pyproj in /usr/local/lib/python3.10/dist-packages (from r5py) (3.6.1) Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from r5py) (2.32.3) Requirement already satisfied: shapely>=2.0 in /usr/local/lib/python3.10/dist-packages (from r5py) (2.0.6) Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2024.1) Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=2.1.0->r5py) (2024.1) Requirement already satisfied: attrs>=19.2.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (24.2.0) Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (2024.7.4) Requirement already satisfied: click~=8.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (8.1.7) Requirement already satisfied: click-plugins>=1.0 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (1.1.1) Requirement already satisfied: cligj>=0.5 in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (0.7.2) Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from fiona->r5py) (1.16.0) Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from geopandas->r5py) (24.1) Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (3.3.2) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (3.8) Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->r5py) (2.0.7) Downloading r5py-0.1.2-py3-none-any.whl (51 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 51.7/51.7 kB 1.4 MB/s eta 0:00:00 Downloading ConfigArgParse-1.7-py3-none-any.whl (25 kB) Downloading JPype1-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (488 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 488.6/488.6 kB 4.7 MB/s eta 0:00:00 Installing collected packages: jpype1, ConfigArgParse, r5py Successfully installed ConfigArgParse-1.7 jpype1-1.5.0 r5py-0.1.2 Collecting mapclassify Downloading mapclassify-2.8.0-py3-none-any.whl.metadata (2.8 kB) Requirement already satisfied: networkx>=2.7 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (3.3) Requirement already satisfied: numpy>=1.23 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.26.4) Requirement already satisfied: pandas!=1.5.0,>=1.4 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (2.1.4) Requirement already satisfied: scikit-learn>=1.0 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.3.2) Requirement already satisfied: scipy>=1.8 in /usr/local/lib/python3.10/dist-packages (from mapclassify) (1.13.1) Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2024.1) Requirement already satisfied: tzdata>=2022.1 in /usr/local/lib/python3.10/dist-packages (from pandas!=1.5.0,>=1.4->mapclassify) (2024.1) Requirement already satisfied: joblib>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from scikit-learn>=1.0->mapclassify) (1.4.2) Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn>=1.0->mapclassify) (3.5.0) Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.2->pandas!=1.5.0,>=1.4->mapclassify) (1.16.0) Downloading mapclassify-2.8.0-py3-none-any.whl (58 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.9/58.9 kB 863.5 kB/s eta 0:00:00 Installing collected packages: mapclassify Successfully installed mapclassify-2.8.0 Requirement already satisfied: folium in /usr/local/lib/python3.10/dist-packages (0.17.0) Requirement already satisfied: branca>=0.6.0 in /usr/local/lib/python3.10/dist-packages (from folium) (0.7.2) Requirement already satisfied: jinja2>=2.9 in /usr/local/lib/python3.10/dist-packages (from folium) (3.1.4) Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from folium) (1.26.4) Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from folium) (2.32.3) Requirement already satisfied: xyzservices in /usr/local/lib/python3.10/dist-packages (from folium) (2024.6.0) Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2>=2.9->folium) (2.1.5) Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (3.3.2) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (3.8) Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (2.0.7) Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->folium) (2024.7.4)
import matplotlib.pyplot as plt
overview_map = population_grid.explore("VALUE", cmap="Reds")
display(overview_map)
print(type(overview_map))
<class 'folium.folium.Map'>
population_grid.plot(column='VALUE', cmap='Reds', legend=True)
<Axes: >
# Allow 12 GB of memory
import sys
sys.argv.append(["--max-memory", "12G"])
import geopandas as gpd
# Assuming population_grid is already defined and is a GeoDataFrame
# Adding a sequential ID column
population_grid['id'] = range(1, len(population_grid) + 1)
# Verify the addition of the ID column
print(population_grid.head())
VALUE geometry id 0 10.120865 MULTIPOLYGON (((34.24958 0.31711, 34.24958 0.3... 1 1 8.948438 MULTIPOLYGON (((34.25126 0.31759, 34.25208 0.3... 2 2 5.794432 MULTIPOLYGON (((34.24759 0.31628, 34.24792 0.3... 3 3 9.713193 MULTIPOLYGON (((34.24875 0.31674, 34.24875 0.3... 4 4 16.873987 MULTIPOLYGON (((34.25708 0.31631, 34.25708 0.3... 5
import folium
from IPython.display import display
# Define latitude and longitude for map center
latitude = 0.062568 # Replace with your desired latitude
longitude = 34.283092 # Replace with your desired longitude
# Create a base map
m = folium.Map(location=[latitude, longitude], zoom_start=12)
# Add your GeoDataFrame to the map using the new ID column
folium.Choropleth(
geo_data=population_grid,
data=population_grid,
columns=['id', 'VALUE'], # Use 'id' and the column for values
key_on='feature.properties.id', # Adjust to match the ID column
fill_color='Reds',
fill_opacity=0.7,
line_opacity=0.2
).add_to(m)
# Display the map
display(m)
# Display the map
display(m)
import folium
from IPython.display import display
latitude = 0.062568
longitude = 34.283092
# Create a simple map
m = folium.Map(location=[latitude, longitude], zoom_start=12)
display(m)
import folium
import geopandas as gpd
# Assuming population_grid is your GeoDataFrame
# Sample latitude and longitude for the map center
latitude = 0.062568
longitude = 34.283092
# Create a base map
m = folium.Map(location=[latitude, longitude], zoom_start=12)
# Convert the GeoDataFrame to GeoJSON format and add to the map
folium.GeoJson(
population_grid,
style_function=lambda x: {
'fillColor': 'red',
'color': 'black',
'weight': 1,
'fillOpacity': 0.5,
}
).add_to(m)
# Display the map
m