<jupyter_start><jupyter_text>CityScan Accessibility Analysis- This analysis will measure accessibility to only schools- Origins are derived from 100m grid blocks coming from WorldPop- The accessibility measure is the time to the nearest facility in seconds Inputs: origins: derived from a WorldPop raster manually using the 'Raster pixels to Points' tool in QGIS 3, and saved as a shapefile destinations: The combination of POIs from Overpass as points and centroids of polygons (QGIS 3 Centoids tool). The two different point layers were merged with the QGIS 'Merge vector Layers' tool. The admin AOI will be used to create a bounding box to download the road network via OSMNX  Import libraries<jupyter_code>import sys, os, inspect, logging, importlib

import geopandas as gpd
import pandas as pd
import numpy as np
import osmnx as ox
import networkx as nx
from shapely.ops import split, unary_union
from shapely.geometry import box, Point

import matplotlib.pyplot as plt
# Get reference to GOSTNets
sys.path.append(r'../../GOSTNets/GOSTNets')
import GOSTnet as gn
# define output folder
inputFolder = r'cityscan_accessibility_analysis_input_folder'
# define output folder
outputFolder = r'../../../cityscan_accessibility_analysis_output_folder'
# define road graph
roadGraph = os.path.join(inputFolder, "OSM_Roads.pickle")
# import extent
city_extent = gpd.read_file(os.path.join(inputFolder, "Addis_AOI.shp"))
# This is the section where we can adjust the road speeds
if not os.path.exists(roadGraph):
    extent = box(*city_extent.total_bounds)
    G = ox.graph_from_polygon(extent, network_type = 'drive_service')
    # This is how time is calculated from the OSMNX length attribute
    G = gn.convert_network_to_time(G, 'length')
    
    # compatible with NetworkX 2.4
    list_of_subgraphs = list(G.subgraph(c).copy() for c in nx.strongly_connected_components(G))
    max_graph = None
    max_edges = 0
    for i in list_of_subgraphs:
        if i.number_of_edges() > max_edges:
            max_edges = i.number_of_edges()
            max_graph = i

    # set your graph equal to the largest sub-graph
    G = max_graph
    
    print('print G')
    nx.write_gpickle(G, roadGraph)
else:
    G = nx.read_gpickle(roadGraph)    
    G = gn.convert_network_to_time(G, 'length')<jupyter_output><empty_output><jupyter_text>Inspect the road graph as a shapefile<jupyter_code>roads = gn.edge_gdf_from_graph(G)
roads[:2]
if not os.path.exists(outputFolder + '/OSM_Roads/OSM_Roads.shp'):
    roads['oneway'] = roads.oneway.astype(int)
    roads = roads[['oneway','length','time','mode','geometry']]
    roads.to_file(outputFolder + '/OSM_Roads')<jupyter_output><empty_output><jupyter_text>Create origins and destinations and snap them to the road graph<jupyter_code># insert origins
origins = gpd.read_file(os.path.join(inputFolder, "world_pop_population_pts.shp"))
# insert destinations
destinations = gpd.read_file(os.path.join(inputFolder, "merged_school_pts.shp"))
# snap the origins to the road graph
snapped_origins = gn.pandana_snap_c(G, origins)
snapped_origins
# snap the destinations to the road graph
snapped_destinations = gn.pandana_snap_c(G, destinations)
originNodes = list(snapped_origins['NN'].unique())
destinationNodes = list(snapped_destinations['NN'].unique())
# calculate OD matrix
OD_matrix = gn.calculate_OD(G, originNodes, destinationNodes, fail_value=-1, weight='time')
#OD_matrix[:3]
closest_facility_per_origin = OD_matrix.min(axis=1)
closest_facility_per_origin[:5]
# calculate accessibility
# For each row, the closest facility is the smallest value in the row

output = snapped_origins.copy()

closest_facility_per_origin = OD_matrix.min(axis=1)

results = pd.DataFrame([originNodes, closest_facility_per_origin]).transpose()
colName = "travel_time_to_closest_facility"
results.columns = ['NN', colName]
results[:5]
output = pd.merge(output, results, on = "NN")
output.to_csv(os.path.join(outputFolder, "addis_accessibility_schools.csv"))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0932733183295824, 'fraction_numerical': 0.0037509377344336083, 'mean_word_length': 5.389776357827476, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '206955', 'license': 'MIT', 'n_tokens_mistral': 1330, 'n_tokens_neox': 1280, 'n_words': 366, 'path': 'Implementations/FY20/ACC_CityScan_accessibility_analysis/CityScan_Accessibility_Analysis.ipynb', 'repo_name': 'worldbank/GOST_PublicGoods', 'size': '3999'}