Beispiel #1
0
def test_plots():

    G = ox.graph_from_place('Piedmont, California, USA', network_type='drive', simplify=False)
    G2 = ox.simplify_graph(G, strict=False)

    # test getting colors
    co = ox.get_colors(n=5, return_hex=True)
    nc = ox.get_node_colors_by_attr(G2, 'osmid')
    ec = ox.get_edge_colors_by_attr(G2, 'length')

    # save a plot to disk as png
    fig, ax = ox.plot_graph(G, save=True, file_format='png')

    # save a plot to disk as svg
    G_simplified = ox.simplify_graph(G)
    fig, ax = ox.plot_graph(G_simplified, show=False, save=True, close=True, file_format='svg')

    G_projected = ox.project_graph(G_simplified)
    fig, ax = ox.plot_graph(G_projected)

    fig, ax = ox.plot_graph(G_projected, fig_height=5, fig_width=5, margin=0.05, axis_off=False, bgcolor='y',
                            file_format='png', filename='x', dpi=180, annotate=True, node_color='k', node_size=5,
                            node_alpha=0.1, node_edgecolor='b', node_zorder=5, edge_color='r', edge_linewidth=2,
                            edge_alpha=0.1, use_geom=False, show=False, save=True, close=True)

    fig, ax = ox.plot_figure_ground(G=G_simplified, file_format='png')
    fig, ax = ox.plot_figure_ground(point=(33.694981, -117.841375), file_format='png')
    fig, ax = ox.plot_figure_ground(address='Denver, Colorado, USA', file_format='png')
Beispiel #2
0
def test_plots():

    G = ox.graph_from_place('Piedmont, California, USA', network_type='drive', simplify=False)
    G2 = ox.simplify_graph(G, strict=False)

    # test getting colors
    co = ox.get_colors(n=5, return_hex=True)
    nc = ox.get_node_colors_by_attr(G2, 'osmid')
    ec = ox.get_edge_colors_by_attr(G2, 'length')

    # save a plot to disk as png
    fig, ax = ox.plot_graph(G, save=True, file_format='png')

    # save a plot to disk as svg
    G_simplified = ox.simplify_graph(G)
    fig, ax = ox.plot_graph(G_simplified, show=False, save=True, close=True, file_format='svg')

    G_projected = ox.project_graph(G_simplified)
    fig, ax = ox.plot_graph(G_projected)

    fig, ax = ox.plot_graph(G_projected, fig_height=5, fig_width=5, margin=0.05, axis_off=False, bgcolor='y',
                            file_format='png', filename='x', dpi=180, annotate=True, node_color='k', node_size=5,
                            node_alpha=0.1, node_edgecolor='b', node_zorder=5, edge_color='r', edge_linewidth=2,
                            edge_alpha=0.1, use_geom=False, show=False, save=True, close=True)

    fig, ax = ox.plot_figure_ground(G=G_simplified, file_format='png')
    fig, ax = ox.plot_figure_ground(point=(33.694981, -117.841375), file_format='png')
    fig, ax = ox.plot_figure_ground(address='Denver, Colorado, USA', file_format='png')
def graph_from_shapefile(path,
                         in_crs=None,
                         custom_standards=None,
                         name='unnamed',
                         retain_all=False,
                         simplify=True):
    """
    Create Networkx Graph from the shapeFile provided.

    :param path: Path of the shapeFile.
    :param in_crs: CRS of the shapeFile. Should be a string in 'EPSG:{number}' format. (Default = 'EPSG:4326')
    :param custom_standards: Dict object used to convert non standard properties attributes to standard
    example = {
        "LINK_ID": "osm_id",
        "DIRONSIGN":"oneway"
    }
    json format Key:Value
    where:
        Key is the Field Name from the shapeFile.
        Value is the standard to convert it to.
    See documentation for more.
    :param name: Name of the Graph to be created.(default = unnamed)
    :param retain_all: if True, return the entire graph even if it is not connected
    :param simplify: Simplify the graph. (default = True)
    :return: Networkx MultiDiGraph
    """
    geojson = shp2geojson(path, custom_standards)
    if in_crs is not None:
        geojson = coordinate_transform(geojson, in_crs=in_crs)
    json_data = geojson2osm_json(geojson)
    g = ox.create_graph(json_data, name, retain_all=retain_all)
    if simplify is True:
        g = ox.simplify_graph(g)
    return g
Beispiel #4
0
def graph_from_shapefile(path, custom_standards=None, name='unnamed', simplify=True):
    """
    Create Networkx Graph from the shapeFile provided.

    :param path: Path of the shapeFile.
    :param custom_standards: Dict object used to convert non standard properties attributes to standard
    example = {
        "LINK_ID": "osm_id",
        "DIRONSIGN":"oneway"
    }
    json format Key:Value
    where:
        Key is the Field Name from the shapeFile.
        Value is the standard to convert it to.
    See documentation for more.
    :param name: Name of the Graph to be created.(default = unnamed)
    :param simplify: Simplify the graph. (default = True)
    :return: Networkx MultiDiGraph
    """
    geojson = shp2geojson(path, custom_standards)
    json_data = geojson2osm_json(geojson)
    g = ox.create_graph(json_data, name)
    if simplify is True:
        g = ox.simplify_graph(g)
    return g
Beispiel #5
0
def composeFiles(fileL):
    """compose a list of graphs from files"""
    graphL = []
    for f in fileL:
        graph1 = ox.load_graphml(filename=f)
    composed_G = nx.compose_all(graphL)
    simp_G = ox.simplify_graph(composed_G)
    return composed_G
Beispiel #6
0
def simplify_graph(G):
	''' strict mode more consistent with non-important mid nodes.'''
	# nc = ['b' if ox.is_endpoint(G, node, strict=True) else 'r' for node in G.nodes()]
	# fig, ax = ox.plot_graph(G, node_color=nc, node_zorder=3)
	G = ox.simplify_graph(G, strict=True)
	if iprint>=2: print("simplify_graph showing simplified graph...")
	if Has_Display: fig, ax = ox.plot_graph(G, node_color='b', node_zorder=3)
	return G
Beispiel #7
0
def load_graph(city_name):
    global graph
    global city
    graph = ox.simplify_graph(ox.graph_from_place(
        city_name + " France",
        simplify=False,
        retain_all=True,
        network_type='drive',
    ))
    city = city_name
Beispiel #8
0
def bike_network(geometry, name):
    G = ox.graph_from_polygon(polygon=geometry,
                              network_type='bike',
                              name=name,
                              retain_all=True,
                              simplify=False)
    #non_cycleways = [(u, v, k) for u, v, k, d in G.edges(keys=True, data=True)
    #                 if not ('cycleway' in d or d['highway'] == 'cycleway')]
    #G.remove_edges_from(non_cycleways)
    G = ox.simplify_graph(G)
    return G
Beispiel #9
0
def test_plots():

    G = ox.graph_from_place('Piedmont, California, USA',
                            network_type='drive',
                            simplify=False)
    G2 = ox.simplify_graph(G, strict=False)
    ec = ox.get_edge_colors_by_attr(G2, 'length')
    fig, ax = ox.plot_graph(G, save=True, file_format='png')

    G_simplified = ox.simplify_graph(G)
    fig, ax = ox.plot_graph(G_simplified,
                            show=False,
                            save=True,
                            close=True,
                            file_format='svg')

    G_projected = ox.project_graph(G_simplified)
    fig, ax = ox.plot_graph(G_projected)

    fig, ax = ox.plot_graph(G_projected,
                            fig_height=5,
                            fig_width=5,
                            margin=0.05,
                            axis_off=False,
                            bgcolor='y',
                            file_format='png',
                            filename='x',
                            dpi=180,
                            annotate=True,
                            node_color='k',
                            node_size=5,
                            node_alpha=0.1,
                            node_edgecolor='b',
                            node_zorder=5,
                            edge_color='r',
                            edge_linewidth=2,
                            edge_alpha=0.1,
                            use_geom=False,
                            show=False,
                            save=True,
                            close=True)
Beispiel #10
0
def print_vehicles(G, V):
    H = ox.simplify_graph(G)
    fig, ax = ox.plot_graph(H, show=False, close=False)
    for v in V.nodes():
        ax.plot(V.nodes[v]['x'], V.nodes[v]['y'], marker='o', color='r')
    for s, t in V.edges():
        ax.plot([V.nodes[s]['x'], V.nodes[t]['x']],
                [V.nodes[s]['y'], V.nodes[t]['y']],
                color='r',
                linewidth=0.1)
    #plt.show()
    plt.savefig(f"trento_car_{len(V.nodes())}_{len(V.edges())}.pdf")
Beispiel #11
0
def download_cambridge_graph(save_path):

    cambridge_ll_bbox = [52.245, 52.150, 0.220, 0.025]
    raw_graph = ox.graph_from_bbox(*cambridge_ll_bbox,
                                   truncate_by_edge=True,
                                   simplify=False,
                                   network_type='drive')

    projected_graph = ox.project_graph(raw_graph)

    simplified_graph = ox.simplify_graph(projected_graph)

    write_gpickle(simplified_graph, save_path)
def get_graph(filename):
    grabber = OSMloader()
    p = OSMParser(concurrency=1,
                  coords_callback=grabber.nodes,
                  ways_callback=grabber.ways)
    p.parse(filename)
    grabber.spinner.finish()
    print ''

    print 'Simplifying graph... '
    graph = max(nx.strongly_connected_component_subgraphs(grabber.graph,
                                                          copy=True),
                key=len)
    return nx.DiGraph(simplify_graph(graph, strict=False))
Beispiel #13
0
    def getBike(self, place):
        useful_tags = ox.settings.useful_tags_way + ['cycleway'] + ['bicycle'] + ['oneway'] + ['bicycle:lanes'] + ['cycleway:right'] + ['cycleway:left'] + ['bicycle_road']
        ox.utils.config(use_cache=True, log_console=True, useful_tags_way=useful_tags)
        G = ox.graph_from_place(query=place, network_type='bike', simplify=False,  retain_all=True)
        attributes = []

        non_cyc = []
        for u,v,k,d in G.edges(keys=True, data=True):
            for a in d:
                name=str(a)+": "+str(d[a])
                excluded = ['osmid', 'ref', 'length', 'width', 'name']
                if a in excluded:
                    pass
                elif name not in attributes:
                    attributes.append(name)
            
            bi = False
            if "bicycle" in d:
                if d['bicycle']=='designated' or d['bicycle']=='official' or d['bicycle']=='track' or d['bicycle']=='use_sidepath':
                    bi = True
            if "bicycle:lanes" in d:
                if "designated" in d['bicycle:lanes']:
                    bi = True
                    
            if d['highway']=='cycleway':
                pass
            elif 'cycleway' in d and d['cycleway'] != "no" and d['cycleway'] != "opposite":
                pass
            elif 'cycleway:right' in d and d['cycleway:right'] != "no":
                pass
            elif 'cycleway:left' in d and d['cycleway:left'] != "no":
                pass
            elif 'bicycle_road' in d and d['bicycle_road'] == "yes":
                pass
            elif bi:
                pass
            else:
                non_cyc.append((u,v,k))

        G.remove_edges_from(non_cyc)
        G = ox.utils_graph.remove_isolated_nodes(G)
        try:
            G = ox.simplify_graph(G)
        except:
            pass
        attributes.sort()
        #print(attributes)
        return G
def bike_network(city):
    try:
        G = ox.graph_from_place(city,
                                network_type='bike',
                                simplify=False,
                                which_result=1)
    except:
        G = ox.graph_from_place(city,
                                network_type='bike',
                                simplify=False,
                                which_result=2)
    #non_cycleways = [(u, v, k) for u, v, k, d in G.edges(keys=True, data=True)
    #                 if not ('cycleway' in d or d['highway'] == 'cycleway')]
    #G.remove_edges_from(non_cycleways)
    #G = ox.remove_isolated_nodes(G)
    G = ox.simplify_graph(G)
    return ox.project_graph(G)
Beispiel #15
0
def return_links_of_interest(graph):
    '''
    Due to the graph network coming straight from osm having nodes at every bend
    in the road, there are far too many roads. Moreover, many roads are quite short
    and so will almost always take less than 15 seconds to traverse. Considering that
    our measurements are spaced 15 seconds apart, we only want to learn the pdfs
    for roads that take around or more than 15 seconds to traverse as we can't exatly
    be sure how long it took to traverse shorter roads. Thus, we only consider modelling
    a subset of the links of the network known as 'links of interest'.

    Parameters:
    ----------
    Graph (networkx multidigraph): Graph that you want to get the links_of_interest from

    Returns:
    --------
    links_of_interest (dictionary): mapping from these 'links of interest' to their corresponding
                                    indices (just an integer from 0-len(links_of_interest)).
    '''

    # speed limit on inner city roads is 50 mph in Porto.
    # We want the time taken on links of interest to be around 15 seconds
    # to reduce our measurement error.
    # Therefore the minimum length of road we are interested in, assuming
    # a min cutoff time of 10 seconds and an average speed of
    # 30 mph is (30*1.6)/3600)*10*1000 ~= 130m
    # use 100m just to be safe
    # This get's rid of roughly half the edges

    #we want to use the simplified graph as regular graph has too many edges
    simple_graph = ox.simplify_graph(graph, strict=True)
    cutoff = 100
    edges = list(simple_graph.edges(data='length'))
    edges_of_interest = {}
    i = 0
    for edge_data in edges:
        edge_name = get_edge_name(edge_data[0], edge_data[1])
        edge_length = edge_data[2]
        if edge_length > cutoff:
            #edge[0] and edge[1] correspond to the nodes
            if edge_name not in edges_of_interest:
                # edges are repeated in edges for some reason
                edges_of_interest[edge_name] = i
                i += 1

    return edges_of_interest
Beispiel #16
0
def simple_get_roads(city):
    """
    Use osmnx to get a simplified version of open street maps for the city
    Writes osm_nodes and osm_ways shapefiles to MAP_FP
    Args:
        city
    Returns:
        None, but creates the following shape files:
           osm_ways.shp - the simplified road network
           osm_nodes.shp - the intersections and dead ends
        And creates the following directory:
           all_nodes - containing edges and nodes directories
               for the unsimplified road network
    """

    G1 = ox.graph_from_place(city, network_type='drive', simplify=False)
    G = ox.simplify_graph(G1)

    # Label endpoints
    streets_per_node = ox.count_streets_per_node(G)
    for node, count in list(streets_per_node.items()):
        if count <= 1:
            G.nodes()[node]['dead_end'] = True

    # osmnx creates a directory for the nodes and edges
    # Store all nodes, since they can be other features
    ox.save_graph_shapefile(G1, filename='all_nodes', folder=MAP_FP)

    # Store simplified network
    ox.save_graph_shapefile(G, filename='temp', folder=MAP_FP)

    # Copy and remove temp directory
    tempdir = os.path.join(MAP_FP, 'temp')
    for filename in os.listdir(os.path.join(tempdir, 'edges')):
        name, extension = filename.split('.')
        shutil.move(os.path.join(tempdir, 'edges', filename),
                    os.path.join(MAP_FP, 'osm_ways.' + extension))
    for filename in os.listdir(os.path.join(tempdir, 'nodes')):
        name, extension = filename.split('.')
        shutil.move(os.path.join(tempdir, 'nodes', filename),
                    os.path.join(MAP_FP, 'osm_nodes.' + extension))
    shutil.rmtree(tempdir)
Beispiel #17
0
def simplifyGraph(G, connection="strong"):
    """simplify a graph"""
    # G = ox.load_graphml(filename=fName)
    print("G nodes: " + str(len(G.nodes())))
    print("G edges: " + str(len(G.edges())))
    G_simp = ox.simplify_graph(G)
    print('simp_G:')
    print("G simp nodes: " + str(len(G_simp.nodes())))
    print("G simp edges: " + str(len(G_simp.edges())))
    if connection == "strong":
        G_connect = max(nx.weakly_connected_component_subgraphs(G_simp), key=len)
    elif connection == "weak":
        G_connect = max(nx.strongly_connected_component_subgraphs(G_simp), key=len)
    elif connection == "undirect":
        G_connect = max(nx.connected_component_subgraphs(G_simp.to_undirected()), key=len)
    else:
        G_connect = G_simp
    print('connected_G:')
    print("G connected nodes: " + str(len(G_connect.nodes())))
    print("G connected edges: " + str(len(G_connect.edges())))
    G_proj = ox.project_graph(G_connect, to_crs={'init': 'epsg:4326'})
    print('proj done')
    return G_proj
Beispiel #18
0
def wkt_to_G(wkt_list, im_file=None, min_subgraph_length_pix=30, 
             min_spur_length_m=5, simplify_graph=True, verbose=False):
    '''Execute all functions'''

    t0 = time.time()
    print ("Running wkt_list_to_nodes_edges()...")
    node_loc_dic, edge_dic = wkt_list_to_nodes_edges(wkt_list)
    t1 = time.time()
    print ("Time to run wkt_list_to_nodes_egdes():", t1 - t0, "seconds")
    
    #print ("node_loc_dic:", node_loc_dic)
    #print ("edge_dic:", edge_dic)
    
    print ("Creating G...")
    G0 = nodes_edges_to_G(node_loc_dic, edge_dic)  
    print ("  len(G.nodes():", len(G0.nodes()))
    print ("  len(G.edges():", len(G0.edges()))
    #for edge_tmp in G0.edges():
    #    print ("\n 0 wtk_to_G():", edge_tmp, G0.edge[edge_tmp[0]][edge_tmp[1]])
    
    
    t2 = time.time()
    print ("Time to run nodes_edges_to_G():", t2-t1, "seconds")
    
    print ("Clean out short subgraphs")
    G0 = clean_sub_graphs(G0, min_length=min_subgraph_length_pix, 
                     max_nodes_to_skip=30,
                     weight='length_pix', verbose=True,
                     super_verbose=False)
    t3 = time.time()
    print ("Time to run clean_sub_graphs():", t3-t2, "seconds")

    if len(G0) == 0:
        return G0
    
#    print ("Simplifying graph")
#    G0 = ox.simplify_graph(G0.to_directed())
#    G0 = G0.to_undirected()
#    #G0 = ox.project_graph(G0)
#    #G_p_init = create_edge_linestrings(G_p_init, remove_redundant=True, verbose=False)
#    t3 = time.time()
#    print ("  len(G.nodes():", len(G0.nodes()))
#    print ("  len(G.edges():", len(G0.edges()))
#    print ("Time to run simplify graph:", t30 - t3, "seconds")
    
    #for edge_tmp in G0.edges():
    #    print ("\n 1 wtk_to_G():", edge_tmp, G0.edge[edge_tmp[0]][edge_tmp[1]])
    
    #edge_tmp = G0.edges()[5]
    #print (edge_tmp, "G0.edge props:", G0.edge[edge_tmp[0]][edge_tmp[1]])

    
    # geo coords
    if im_file:
        print ("Running get_node_geo_coords()...")
        G1 = get_node_geo_coords(G0, im_file, verbose=verbose)
        t4= time.time()
        print ("Time to run get_node_geo_coords():", t4-t3, "seconds")

        print ("Running get_edge_geo_coords()...")
        G1 = get_edge_geo_coords(G1, im_file, verbose=verbose)
        t5 = time.time()
        print ("Time to run get_edge_geo_coords():", t5-t4, "seconds")

        print("pre projection...")
        node = list(G1.nodes())[-1]
        print(node, "random node props:", G1.nodes[node])
        # print an edge
        edge_tmp = list(G1.edges())[-1]
        print(edge_tmp, "random edge props:", G1.get_edge_data(edge_tmp[0], edge_tmp[1]))

        print ("projecting graph...")
        G_projected = ox.project_graph(G1)
        
        print("post projection...")
        node = list(G_projected.nodes())[-1]
        print(node, "random node props:", G_projected.nodes[node])
        # print an edge
        edge_tmp = list(G_projected.edges())[-1]
        print(edge_tmp, "random edge props:", G_projected.get_edge_data(edge_tmp[0], edge_tmp[1]))

        t6 = time.time()
        print ("Time to project graph:", t6-t5, "seconds")

        # simplify
        #G_simp = ox.simplify_graph(G_projected.to_directed())
        #ox.plot_graph(G_projected)
        #G1.edge[19][22]
        
        Gout = G_projected #G_simp
    
    else:
        Gout = G0


    ###########################################################################
    # remove short edges
    t31 = time.time()
    Gout = remove_short_edges(Gout, min_spur_length_m=min_spur_length_m)
    t32 = time.time()
    print("Time to remove_short_edges():", t32 - t31, "seconds")
    ###########################################################################
    
    if simplify_graph:
        print ("Simplifying graph")
        t7 = time.time()
        G0 = ox.simplify_graph(Gout.to_directed())
        Gout = G0.to_undirected()
        #Gout = ox.project_graph(G0)
        
        t8 = time.time()
        print ("Time to run simplify graph:", t8-t7, "seconds")
        # When the simplify funciton combines edges, it concats multiple
        #  edge properties into a list.  This means that 'geometry_pix' is now
        #  a list of geoms.  Convert this to a linestring with 
        #   shaply.ops.linemergeconcats 
        print ("Merge 'geometry' linestrings...")
        keys_tmp = ['geometry_pix', 'geometry_latlon_wkt', 'geometry_utm_wkt']
        for key_tmp in keys_tmp:
            print ("Merge", key_tmp, "...")
            for i,(u,v,attr_dict) in enumerate(Gout.edges(data=True)):
                if (i % 10000) == 0:
                    print (i, u , v)
                geom = attr_dict[key_tmp]
                #print (i, u, v, "geom:", geom)
                #print ("  type(geom):", type(geom))
                
                if type(geom) == list:
                    # check if the list items are wkt strings, if so, create
                    #   linestrigs
                    if (type(geom[0]) == str):# or (type(geom_pix[0]) == unicode):
                        geom = [shapely.wkt.loads(ztmp) for ztmp in geom]
                    # merge geoms
                    #geom = shapely.ops.linemerge(geom)
                    #attr_dict[key_tmp] =  geom
                    attr_dict[key_tmp] = shapely.ops.linemerge(geom)
                elif type(geom) == str:
                    attr_dict[key_tmp] = shapely.wkt.loads(geom)
                else:
                    pass

        # assign 'geometry' tag to geometry_utm_wkt
        for i,(u,v,attr_dict) in enumerate(Gout.edges(data=True)):
            if verbose:
                print ("Create 'geometry' field in edges...")
            #geom_pix = attr_dict[key_tmp]
            line = attr_dict['geometry_utm_wkt']       
            if type(line) == str:# or type(line) == unicode:
                attr_dict['geometry'] = shapely.wkt.loads(line) 
            else:
                attr_dict['geometry'] = attr_dict['geometry_utm_wkt']       
            # update wkt_pix?
            #print ("attr_dict['geometry_pix':", attr_dict['geometry_pix'])
            attr_dict['wkt_pix'] = attr_dict['geometry_pix'].wkt
        
            # update 'length_pix'
            attr_dict['length_pix'] = np.sum([attr_dict['length_pix']])
            
        # Gout = ox.project_graph(Gout) 
    
    # get a few stats (and set to graph properties)
    logger1.info("Number of nodes: {}".format(len(Gout.nodes())))
    logger1.info("Number of edges: {}".format(len(Gout.edges())))
    #print ("Number of nodes:", len(Gout.nodes()))
    #print ("Number of edges:", len(Gout.edges()))
    Gout.graph['N_nodes'] = len(Gout.nodes())
    Gout.graph['N_edges'] = len(Gout.edges())
    
    # get total length of edges
    tot_meters = 0
    for i,(u,v,attr_dict) in enumerate(Gout.edges(data=True)):
        tot_meters  += attr_dict['length'] 
    print ("Length of edges (km):", tot_meters/1000)
    Gout.graph['Tot_edge_km'] = tot_meters/1000

    print ("G.graph:", Gout.graph)
    
    t7 = time.time()
    print ("Total time to run wkt_to_G():", t7-t0, "seconds")
    
    #for edge_tmp in Gout.edges():
    #   print ("\n 2 wtk_to_G():", edge_tmp, Gout.edge[edge_tmp[0]][edge_tmp[1]])

    
    return Gout
def simple_get_roads(config, mapfp):
    """
    Use osmnx to get a simplified version of open street maps for the city
    Writes osm_nodes and osm_ways shapefiles to mapfp
    Args:
        config object
    Returns:
        None
        This function creates the following files
           features.geojson - traffic signals, crosswalks and intersections
           osm_ways.shp - the simplified road network
           osm_nodes.shp - the intersections and dead ends
    """

    ox.settings.useful_tags_path.append('cycleway')
    G1 = get_graph(config)
    G = ox.simplify_graph(G1)

    # Label endpoints
    streets_per_node = ox.count_streets_per_node(G)
    for node, count in list(streets_per_node.items()):
        if count <= 1:
            G.nodes()[node]['dead_end'] = True
            G1.nodes()[node]['dead_end'] = True

    # osmnx creates a directory for the nodes and edges
    # Store all nodes, since they can be other features

    # Get relevant node features out of the unsimplified graph
    nodes, data = zip(*G1.nodes(data=True))
    gdf_nodes = geopandas.GeoDataFrame(list(data), index=nodes)
    node_feats = gdf_nodes[gdf_nodes['highway'].isin(
        ['crossing', 'traffic_signals'])]
    intersections = gdf_nodes[gdf_nodes['dead_end'] == True]

    names = {'traffic_signals': 'signal', 'crossing': 'crosswalk'}
    features = []
    for _, row in node_feats.iterrows():
        features.append(
            geojson.Feature(
                geometry=geojson.Point((row['x'], row['y'])),
                id=row['osmid'],
                properties={'feature': names[row['highway']]},
            ))
    for _, row in intersections.iterrows():
        features.append(
            geojson.Feature(
                geometry=geojson.Point((row['x'], row['y'])),
                id=row['osmid'],
                properties={'feature': 'intersection'},
            ))

    features = geojson.FeatureCollection(features)

    with open(os.path.join(mapfp, 'features.geojson'), "w") as f:
        json.dump(features, f)

    # Store simplified network
    ox.save_graph_shapefile(G, filename='temp', folder=mapfp)

    # Copy and remove temp directory
    tempdir = os.path.join(mapfp, 'temp')
    for filename in os.listdir(os.path.join(tempdir, 'edges')):
        _, extension = filename.split('.')
        shutil.move(os.path.join(tempdir, 'edges', filename),
                    os.path.join(mapfp, 'osm_ways.' + extension))
    for filename in os.listdir(os.path.join(tempdir, 'nodes')):
        _, extension = filename.split('.')
        shutil.move(os.path.join(tempdir, 'nodes', filename),
                    os.path.join(mapfp, 'osm_nodes.' + extension))
    shutil.rmtree(tempdir)
def graph_from_jsons(response_jsons,
                     network_type='all_private',
                     simplify=True,
                     retain_all=False,
                     truncate_by_edge=False,
                     name='unnamed',
                     timeout=180,
                     memory=None,
                     max_query_area_size=50 * 1000 * 50 * 1000,
                     clean_periphery=True,
                     infrastructure='way["highway"]'):
    """
    Create a networkx graph from OSM data within the spatial boundaries of the passed-in shapely polygon.
    This is a modified routine from osmnx
    Parameters
    ----------
    response_jsons : list of responses from osmnx
        the shape to get network data within. coordinates should be in units of
        latitude-longitude degrees.
    network_type : string
        what type of street network to get
    simplify : bool
        if true, simplify the graph topology
    retain_all : bool
        if True, return the entire graph even if it is not connected
    truncate_by_edge : bool
        if True retain node if it's outside bbox but at least one of node's
        neighbors are within bbox
    name : string
        the name of the graph
    timeout : int
        the timeout interval for requests and to pass to API
    memory : int
        server memory allocation size for the query, in bytes. If none, server
        will use its default allocation size
    max_query_area_size : float
        max size for any part of the geometry, in square degrees: any polygon
        bigger will get divided up for multiple queries to API
    clean_periphery : bool
        if True (and simplify=True), buffer 0.5km to get a graph larger than
        requested, then simplify, then truncate it to requested spatial extent
    infrastructure : string
        download infrastructure of given type (default is streets (ie, 'way["highway"]') but other
        infrastructures may be selected like power grids (ie, 'way["power"~"line"]'))
    Returns
    -------
    networkx multidigraph
    """

    if clean_periphery and simplify:

        g_buffered = ox.create_graph(response_jsons,
                                     name=name,
                                     retain_all=True,
                                     network_type=network_type)

        # simplify the graph topology
        g = ox.simplify_graph(g_buffered)

        # count how many street segments in buffered graph emanate from each
        # intersection in un-buffered graph, to retain true counts for each
        # intersection, even if some of its neighbors are outside the polygon
        g.graph['streets_per_node'] = ox.count_streets_per_node(
            g, nodes=g.nodes())

    else:

        # create the graph from the downloaded data
        g = ox.create_graph(response_jsons,
                            name=name,
                            retain_all=True,
                            network_type=network_type)

        # simplify the graph topology as the last step. don't truncate after
        # simplifying or you may have simplified out to an endpoint beyond the
        # truncation distance, in which case you will then strip out your entire
        # edge
        if simplify:
            g = ox.simplify_graph(g)

    return g
Beispiel #21
0
                 edge_width=1,
                 x_lim=(min_x, max_x),
                 y_lim=(min_y, max_y),
                 dpi=200,
                 path=_path)


# Let's use OSMnx to fetch an OSM graph
# We'll use the same raw network for both workflows (hence simplify=False)
multi_di_graph_raw = ox.graph_from_point((lat, lng), dist=1250, simplify=False)

# Workflow 1: Using OSMnx for simplification
# ==========================================
# explicit simplification via OSMnx
multi_di_graph_utm = ox.project_graph(multi_di_graph_raw)
multi_di_graph_simpl = ox.simplify_graph(multi_di_graph_utm)
multi_di_graph_cons = ox.consolidate_intersections(multi_di_graph_simpl,
                                                   tolerance=10,
                                                   dead_ends=True)
# let's use the same plotting function for both scenarios to aid visual comparisons
multi_graph_cons = graphs.nX_from_OSMnx(multi_di_graph_cons, tolerance=50)
simple_plot(multi_graph_cons, 'images/osmnx_simplification.png')

# WORKFLOW 2: Using cityseer for simplification
# =============================================
# let's convert the OSMnx graph to cityseer compatible `multiGraph`
G_raw = graphs.nX_from_OSMnx(multi_di_graph_raw)
# convert to UTM
G = graphs.nX_wgs_to_utm(G_raw)
# infer geoms
G = graphs.nX_simple_geoms(G)
Beispiel #22
0
def wkt_to_G(params):
    '''Convert wkt to G with geospatial info.'''
    wkt_list, im_file, min_subgraph_length_pix, \
        node_iter, edge_iter, \
        simplify_graph, \
        rdp_epsilon,\
        manually_reproject_nodes, \
        out_file, pickle_protocol, \
        n_threads, verbose \
        = params

    node_loc_dic, edge_dic = wkt_list_to_nodes_edges(wkt_list,
                                                     node_iter=node_iter,
                                                     edge_iter=edge_iter)
    G0 = nodes_edges_to_G(node_loc_dic, edge_dic)

    # This graph will have a unique edge for each line segment, meaning that
    #  many nodes will have degree 2 and be in the middle of a long edge.
    # run clean_sub_graph() in 04_skeletonize.py?  - Nope, do it here
    # so that adding small terminals works better...
    G1 = clean_sub_graphs(G0,
                          min_length=min_subgraph_length_pix,
                          weight='length_pix',
                          verbose=verbose,
                          super_verbose=False)
    if len(G1) == 0:
        return G1

    # geo coords
    if im_file:
        G1 = get_node_geo_coords(G1, im_file, verbose=verbose)
        G1 = get_edge_geo_coords(G1, im_file, verbose=verbose)

        node = list(G1.nodes())[-1]
        if verbose:
            print(node, "random node props:", G1.nodes[node])
            # print an edge
            edge_tmp = list(G1.edges())[-1]
            print(edge_tmp, "random edge props:",
                  G1.get_edge_data(edge_tmp[0], edge_tmp[1]))

        G_projected = ox.project_graph(G1)
        # get geom wkt (for printing/viewing purposes)
        for i, (u, v, attr_dict) in enumerate(G_projected.edges(data=True)):
            # attr_dict['geometry_wkt'] = attr_dict['geometry'].wkt # broken
            attr_dict['geometry_wkt'] = attr_dict['geometry_utm_wkt']
        if verbose:
            node = list(G_projected.nodes())[-1]
            print(node, "random node props:", G_projected.nodes[node])
            # print an edge
            edge_tmp = list(G_projected.edges())[-1]
            print(edge_tmp, "random edge props:",
                  G_projected.get_edge_data(edge_tmp[0], edge_tmp[1]))

        Gout = G_projected
    else:
        Gout = G0

    if simplify_graph:
        # 'geometry' tag breaks simplify, so make it a wkt
        for i, (u, v, attr_dict) in enumerate(Gout.edges(data=True)):
            if 'geometry' in attr_dict.keys():
                attr_dict['geometry'] = attr_dict['geometry'].wkt

        G0 = ox.simplify_graph(Gout.to_directed())
        G0 = G0.to_undirected()
        # reprojecting graph screws up lat lon, so convert to string?
        # Gout = ox.project_graph(G0) # broken
        Gout = G0

        if verbose:
            node = list(Gout.nodes())[-1]
            print(node, "random node props:", Gout.nodes[node])
            # print an edge
            edge_tmp = list(Gout.edges())[-1]
            print(edge_tmp, "random edge props:",
                  Gout.get_edge_data(edge_tmp[0], edge_tmp[1]))

        # When the simplify funciton combines edges, it concats multiple
        #  edge properties into a list.  This means that 'geometry_pix' is now
        #  a list of geoms.  Convert this to a linestring with
        #   shaply.ops.linemergeconcats

        # BUG, GOOF, ERROR IN OSMNX PROJECT, SO NEED TO MANUALLY SET X, Y FOR NODES!!??
        if manually_reproject_nodes:
            # make sure geometry is utm for nodes?
            for i, (n, attr_dict) in enumerate(Gout.nodes(data=True)):
                attr_dict['x'] = attr_dict['utm_east']
                attr_dict['y'] = attr_dict['utm_north']

        if verbose:
            print("Merge 'geometry' linestrings...")
        keys_tmp = [
            'geometry_wkt', 'geometry_pix', 'geometry_latlon_wkt',
            'geometry_utm_wkt'
        ]
        for key_tmp in keys_tmp:
            if verbose:
                print("Merge", key_tmp, "...")
            for i, (u, v, attr_dict) in enumerate(Gout.edges(data=True)):
                if key_tmp not in attr_dict.keys():
                    continue
                geom = attr_dict[key_tmp]

                if type(geom) == list:
                    # check if the list items are wkt strings, if so, create
                    #   linestrigs
                    if (type(geom[0]) == str):
                        geom = [shapely.wkt.loads(ztmp) for ztmp in geom]
                    # merge geoms
                    geom_out = shapely.ops.linemerge(geom)
                elif type(geom) == str:
                    geom_out = shapely.wkt.loads(geom)
                else:
                    geom_out = geom

                # now straighten edge with rdp
                if rdp_epsilon > 0:
                    coords = list(geom_out.coords)
                    new_coords = rdp.rdp(coords, epsilon=rdp_epsilon)
                    geom_out_rdp = LineString(new_coords)
                    geom_out_final = geom_out_rdp
                else:
                    geom_out_final = geom_out

                len_out = geom_out_final.length

                # updata edge properties
                attr_dict[key_tmp] = geom_out_final

                # update length
                if key_tmp == 'geometry_pix':
                    attr_dict['length_pix'] = len_out
                if key_tmp == 'geometry_utm_wkt':
                    attr_dict['length_utm'] = len_out

        # assign 'geometry' tag to geometry_wkt
        # !! assign 'geometry' tag to geometry_utm_wkt
        key_tmp = 'geometry_wkt'  # 'geometry_utm_wkt'
        for i, (u, v, attr_dict) in enumerate(Gout.edges(data=True)):
            line = attr_dict['geometry_utm_wkt']
            if type(line) == str:
                attr_dict['geometry'] = shapely.wkt.loads(line)
            else:
                attr_dict['geometry'] = attr_dict[key_tmp]
            attr_dict['geometry_wkt'] = attr_dict['geometry'].wkt

            # set length
            attr_dict['length'] = attr_dict['geometry'].length
            # update wkt_pix?
            attr_dict['wkt_pix'] = attr_dict['geometry_pix'].wkt
            # update 'length_pix'
            attr_dict['length_pix'] = np.sum([attr_dict['length_pix']])

    # print a random node and edge
    if verbose:
        node_tmp = list(Gout.nodes())[-1]
        print(node_tmp, "random node props:", Gout.nodes[node_tmp])
        # print an edge
        edge_tmp = list(Gout.edges())[-1]
        print("random edge props for edge:", edge_tmp, " = ",
              Gout.edges[edge_tmp[0], edge_tmp[1], 0])

    # get a few stats (and set to graph properties)
    Gout.graph['N_nodes'] = len(Gout.nodes())
    Gout.graph['N_edges'] = len(Gout.edges())

    # get total length of edges
    tot_meters = 0
    for i, (u, v, attr_dict) in enumerate(Gout.edges(data=True)):
        tot_meters += attr_dict['length']
    if verbose:
        print("Length of edges (km):", tot_meters / 1000)
    Gout.graph['Tot_edge_km'] = tot_meters / 1000

    if verbose:
        print("G.graph:", Gout.graph)

    # save graph
    nx.write_gpickle(Gout, out_file, protocol=pickle_protocol)
Beispiel #23
0
def wkt_to_G(wkt_list,
             im_file=None,
             min_subgraph_length_pix=30,
             simplify_graph=True,
             verbose=False):
    if verbose:
        print("Running wkt_list_to_nodes_edges()...")
    node_loc_dic, edge_dic = wkt_list_to_nodes_edges(wkt_list)

    if verbose:
        print("Creating G...")
    G0 = nodes_edges_to_G(node_loc_dic, edge_dic)
    if verbose:
        print("  len(G.nodes():", len(G0.nodes()))
        print("  len(G.edges():", len(G0.edges()))

    if verbose:
        print("Clean out short subgraphs")
    G0 = clean_sub_graphs(G0,
                          min_length=min_subgraph_length_pix,
                          max_nodes_to_skip=30,
                          weight='length_pix',
                          verbose=False,
                          super_verbose=False)

    if len(G0) == 0:
        return G0

    # geo coords
    if im_file:
        if verbose:
            print("Running get_node_geo_coords()...")
        G1 = get_node_geo_coords(G0, im_file, verbose=verbose)

        if verbose:
            print("Running get_edge_geo_coords()...")
        G1 = get_edge_geo_coords(G1, im_file, verbose=verbose)

        if verbose:
            print("projecting graph...")
        G_projected = ox.project_graph(G1)

        Gout = G_projected  #G_simp
    else:
        Gout = G0

    if simplify_graph:
        if verbose:
            print("Simplifying graph")
        G0 = ox.simplify_graph(Gout.to_directed())
        G0 = G0.to_undirected()
        Gout = ox.project_graph(G0)
        if verbose:
            print("Merge 'geometry' linestrings...")
        keys_tmp = ['geometry_pix', 'geometry_latlon_wkt', 'geometry_utm_wkt']
        for key_tmp in keys_tmp:
            if verbose:
                print("Merge", key_tmp, "...")
            for i, (u, v, attr_dict) in enumerate(Gout.edges(data=True)):
                if (i % 10000) == 0:
                    if verbose:
                        print(i, u, v)
                geom = attr_dict[key_tmp]
                #print (i, u, v, "geom:", geom)
                #print ("  type(geom):", type(geom))

                if type(geom) == list:
                    # check if the list items are wkt strings, if so, create
                    #   linestrigs
                    if (type(geom[0]) == str
                        ):  # or (type(geom_pix[0]) == unicode):
                        geom = [shapely.wkt.loads(ztmp) for ztmp in geom]
                    # merge geoms
                    #geom = shapely.ops.linemerge(geom)
                    #attr_dict[key_tmp] =  geom
                    attr_dict[key_tmp] = shapely.ops.linemerge(geom)
                elif type(geom) == str:
                    attr_dict[key_tmp] = shapely.wkt.loads(geom)
                else:
                    pass

        # assign 'geometry' tag to geometry_utm_wkt
        for i, (u, v, attr_dict) in enumerate(Gout.edges(data=True)):
            if verbose:
                print("Create 'geometry' field in edges...")
            #geom_pix = attr_dict[key_tmp]
            line = attr_dict['geometry_utm_wkt']
            if type(line) == str:  # or type(line) == unicode:
                attr_dict['geometry'] = shapely.wkt.loads(line)
            else:
                attr_dict['geometry'] = attr_dict['geometry_utm_wkt']
            # update wkt_pix?
            #print ("attr_dict['geometry_pix':", attr_dict['geometry_pix'])
            attr_dict['wkt_pix'] = attr_dict['geometry_pix'].wkt

            # update 'length_pix'
            attr_dict['length_pix'] = np.sum([attr_dict['length_pix']])

        Gout = ox.project_graph(Gout)

    if verbose:
        # get a few stats (and set to graph properties)
        print("Number of nodes: {}".format(len(Gout.nodes())))
        print("Number of edges: {}".format(len(Gout.edges())))
        #print ("Number of nodes:", len(Gout.nodes()))
        #print ("Number of edges:", len(Gout.edges()))
    Gout.graph['N_nodes'] = len(Gout.nodes())
    Gout.graph['N_edges'] = len(Gout.edges())

    # get total length of edges
    tot_meters = 0
    for i, (u, v, attr_dict) in enumerate(Gout.edges(data=True)):
        tot_meters += attr_dict['length']
    if verbose:
        print("Length of edges (km):", tot_meters / 1000)
    Gout.graph['Tot_edge_km'] = tot_meters / 1000

    if verbose:
        print("G.graph:", Gout.graph)

    return Gout
Beispiel #24
0
import scipy as sp


if False:
    print("-------------graph-style-examples-----------------")
    print(trajB.shape)
    trajM = trajB.pivot_table(index="origin", columns="destination", values="n", aggfunc=np.sum)
    setR = trajM.index.isin(trajM.columns)
    setC = trajM.columns.isin(trajM.index)
    trajM = trajM.loc[setR, setC]
    plt.imshow(trajM.values)
    plt.show()

    trajS = sp.sparse.coo_matrix(trajM, dtype=np.int8)
    G = nx.Graph(trajS)
    simp_G = ox.simplify_graph(G)

    val_map = {'A': 1.0, 'D': 0.5714285714285714, 'H': 0.0}
    values = [val_map.get(node, 0.45) for node in G.nodes()]
    edge_labels = dict([((u, v,), d['weight']) for u, v, d in G.edges(data=True)])
    red_edges = [('C', 'D'), ('D', 'A')]
    edge_colors = ['black' if not edge in red_edges else 'red' for edge in G.edges()]
    pos = nx.spring_layout(G)
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
    nx.draw(G, pos, node_color=values, node_size=1500, edge_color=edge_colors, edge_cmap=plt.cm.Reds)
    plt.show()

    G = nx.florentine_families_graph()
    adjacency_matrix = nx.adjacency_matrix(G)
    G = nx.fast_gnp_random_graph(100, 0.04)
    adj_matrix = nx.adjacency_matrix(G)
def analyze_city(boundary, crs, local_edges):
    """Analyze correspondence between Local and OSM bikeways throughout a city.

    Parameters
    ----------
    boundary : :class:`shapely.geometry.Polygon`
        City boundary projected in WGS 84

    crs : epsg coordinate system 
        Local coordinate system in meters (e.g., UTM 10: {'init': 'epsg:26910'})

    local_edges : :class:`geopandas.GeoDataFrame`
        Output from `structure_bikeways_shapefile`

    Returns
    -------
    :obj:`tuple`
        * :class:`pandas.DataFrame`
            Output from `summarize_bikeway_correspondance`
        * :class:`geopandas.GeoDataFrame`
            OSM edges with OSM and local bikeway data attached
    """

    # Define OSM tag filter
    # Importantly, no paths with 'highway':'service' or 'highway':'motorway' tags will be returned
    tag_filter = (
        '["area"!~"yes"]["highway"!~"service|footway|motor|proposed|construction|abandoned|platform|raceway"]'
        '["bicycle"!~"no"]["access"!~"private"]')

    # Download the OSM data
    overpass_jsons = ox.osm_net_download(boundary, custom_filter=tag_filter)
    overpass_json = sp.merge_overpass_jsons(overpass_jsons)

    # Define bikeway columns and associated labels
    bikeway_types = [
        'off_street_path', 'bike_blvd', 'separated_bike_lane', 'bike_lane',
        'shoulder', 'sharrow', 'bike_route'
    ]

    # Parse Overpass JSON into bikeway types
    overpass_parsed = sp.parse_osm_tags(overpass_json,
                                        bikeway_types,
                                        true_value=1,
                                        false_value=0,
                                        none_value=np.nan)

    # Specify attributes to include in graph
    path_tags = (bikeway_types + ['highway'])
    ox.config(useful_tags_path=path_tags)
    # Convert json to graph
    G = ox.create_graph([overpass_parsed])
    # Simply graph by removing all nodes that are not intersections or dead ends
    G = ox.simplify_graph(G, strict=True)
    # Make graph undirected
    G = nx.to_undirected(G)
    # Convert graph to geodataframes
    osm_edges = ox.graph_to_gdfs(G, nodes=False)
    # Project to local coordinate system
    osm_edges = osm_edges.to_crs(crs)

    # Project city boundary to local coordinate system
    boundary, _ = ox.project_geometry(boundary, to_crs=crs)

    # Constrain edges to those intersecting the city boundary polygon
    osm_edges = sp.gdf_intersecting_polygon(osm_edges, boundary)

    # Summarize bikeway values stored in lists
    osm_edges[bikeway_types] = osm_edges[bikeway_types].applymap(
        lambda x: sp.nan_any(x, 1, np.nan))

    # Idenfity largest available highway type
    def largest_highway(highways):
        # Specify highway order,
        # largest (least bikable) to smallest (most bikable)
        highway_order = [
            'trunk', 'primary', 'secondary', 'tertiary', 'unclassified',
            'residential', 'living_street', 'cycleway'
        ]
        highways = sp.listify(highways)
        # Strip '_link' from tags
        highways = [x[:-5] if x[-5:] == '_link' else x for x in highways]
        # If list includes one of these tags, return the biggest one
        ranked_highways = [x for x in highways if x in highway_order]
        if len(ranked_highways) > 0:
            ranks = [highway_order.index(x) for x in ranked_highways]
            return highway_order[min(ranks)]
        # Otherwise, return 'other'
        else:
            return 'other'

    osm_edges['highway'] = osm_edges['highway'].apply(largest_highway)

    # Restrict edges to bikeable highway types
    bikable = [
        'primary', 'secondary', 'tertiary', 'unclassified', 'residential',
        'living_street', 'cycleway'
    ]
    osm_edges = osm_edges[osm_edges['highway'].isin(bikable)].copy()

    # Project local edges to local coordinate system
    local_edges = local_edges.to_crs(crs)

    # Restrict to local edges intersecting the city boundary
    local_edges = sp.gdf_intersecting_polygon(local_edges, boundary)

    # Match local edges to OSM edges
    analysis_columns = bikeway_types + ['geometry']
    # Match dataframes
    osm_matches = sp.match_lines_by_hausdorff(
        sp.select_columns(
            osm_edges, analysis_columns,
            suffix='_osm').rename(columns={'geometry_osm': 'geometry'}),
        sp.select_columns(
            local_edges, analysis_columns,
            suffix='_local').rename(columns={'geometry_local': 'geometry'}),
        constrain_target_features=True,
        distance_tolerance=20,
        azimuth_tolerance=20,
        match_fields=True)

    # Identify local and osm bikeway columns
    joint_bikeway_cols = [
        column for column in osm_matches.columns
        if any(bikeway in column for bikeway in bikeway_types)
    ]

    # Reduce lists to a single single binary value
    osm_matches[joint_bikeway_cols] = osm_matches[joint_bikeway_cols].applymap(
        lambda x: sp.nan_any(x, 1, np.nan))

    # Drop records without a bikeway in either dataset
    osm_matches = osm_matches.dropna(how='all', subset=joint_bikeway_cols)

    # Reclassify NaN values as 0
    osm_matches = osm_matches.fillna(0)

    # Function fo calculate composite bikeways
    def composite_columns(matches, columns, suffix):
        # Select relevent columns
        relevent_columns = sp.select_columns(matches,
                                             [x + suffix for x in columns])
        # Assess whether there are any values of 1 across each row
        return relevent_columns.apply(lambda x: sp.nan_any(x, 1, 0), axis=1)

    # Define exclusive and shared bikeway types
    exclusive_bikeways = ['bike_lane', 'separated_bike_lane']
    shared_bikeways = ['bike_blvd', 'sharrow', 'bike_route']

    # Calculate composite of exclusive bikeways
    osm_matches['exclusive_bikeway_osm'] = composite_columns(
        osm_matches, exclusive_bikeways, '_osm')
    osm_matches['exclusive_bikeway_local'] = composite_columns(
        osm_matches, exclusive_bikeways, '_local')

    # Calculate composite of shared bikeways
    osm_matches['shared_bikeway_osm'] = composite_columns(
        osm_matches, shared_bikeways, '_osm')
    osm_matches['shared_bikeway_local'] = composite_columns(
        osm_matches, shared_bikeways, '_local')

    # Calculate composite of all bikeways
    osm_matches['any_bikeway_osm'] = composite_columns(osm_matches,
                                                       bikeway_types, '_osm')
    osm_matches['any_bikeway_local'] = composite_columns(
        osm_matches, bikeway_types, '_local')

    # Calculate the length of each edge
    osm_matches['length'] = osm_matches['geometry'].apply(lambda x: x.length)

    # Add labels to bikeway types
    bikeway_labels = [
        'Off Street Path', 'Bike Boulevard', 'Separated Bike Lane',
        'Bike Lane', 'Shoulder', 'Sharrow', 'Bike Route'
    ]
    bikeway_labels = OrderedDict(zip(bikeway_types, bikeway_labels))
    # Add labels for composite bikeway types
    bikeway_labels.update({'exclusive_bikeway': 'Exclusive'})
    bikeway_labels.update({'shared_bikeway': 'Shared'})
    bikeway_labels.update({'any_bikeway': 'Any'})

    # Calculate summaries
    summaries = summarize_bikeway_correspondance(osm_matches, bikeway_labels)

    return summaries, osm_matches
Beispiel #26
0
def simple_get_roads(config):
    """
    Use osmnx to get a simplified version of open street maps for the city
    Writes osm_nodes and osm_ways shapefiles to MAP_FP
    Args:
        city
    Returns:
        None, but creates the following shape files:
           osm_ways.shp - the simplified road network
           osm_nodes.shp - the intersections and dead ends
        And creates the following directory:
           all_nodes - containing edges and nodes directories
               for the unsimplified road network
    """

    # confirm if a polygon is available for this city, which determines which
    # graph function is appropriate
    print("searching nominatim for " + str(config['city']) + " polygon")
    polygon_pos = find_osm_polygon(config['city'])

    if (polygon_pos is not None):
        print("city polygon found in OpenStreetMaps at position " +
              str(polygon_pos) + ", building graph of roads within " +
              "specified bounds")
        G1 = ox.graph_from_place(config['city'],
                                 network_type='drive',
                                 simplify=False,
                                 which_result=polygon_pos)

    else:
        # City & lat+lng+radius required from config to graph from point
        if ('city' not in list(config.keys()) or config['city'] is None):
            sys.exit('city is required in config file')

        if ('city_latitude' not in list(config.keys())
                or config['city_latitude'] is None):
            sys.exit('city_latitude is required in config file')

        if ('city_longitude' not in list(config.keys())
                or config['city_longitude'] is None):
            sys.exit('city_longitude is required in config file')

        if ('city_radius' not in list(config.keys())
                or config['city_radius'] is None):
            sys.exit('city_radius is required in config file')

        print("no city polygon found in OpenStreetMaps, building graph of " +
              "roads within " + str(config['city_radius']) + "km of city " +
              str(config['city_latitude']) + " / " +
              str(config['city_longitude']))
        G1 = ox.graph_from_point(
            (config['city_latitude'], config['city_longitude']),
            distance=config['city_radius'] * 1000,
            network_type='drive',
            simplify=False)

    G = ox.simplify_graph(G1)

    # Label endpoints
    streets_per_node = ox.count_streets_per_node(G)
    for node, count in list(streets_per_node.items()):
        if count <= 1:
            G.nodes()[node]['dead_end'] = True

    # osmnx creates a directory for the nodes and edges
    # Store all nodes, since they can be other features
    ox.save_graph_shapefile(G1, filename='all_nodes', folder=MAP_FP)

    # Store simplified network
    ox.save_graph_shapefile(G, filename='temp', folder=MAP_FP)

    # Copy and remove temp directory
    tempdir = os.path.join(MAP_FP, 'temp')
    for filename in os.listdir(os.path.join(tempdir, 'edges')):
        name, extension = filename.split('.')
        shutil.move(os.path.join(tempdir, 'edges', filename),
                    os.path.join(MAP_FP, 'osm_ways.' + extension))
    for filename in os.listdir(os.path.join(tempdir, 'nodes')):
        name, extension = filename.split('.')
        shutil.move(os.path.join(tempdir, 'nodes', filename),
                    os.path.join(MAP_FP, 'osm_nodes.' + extension))
    shutil.rmtree(tempdir)
Beispiel #27
0
def wkt_to_G(params):
    '''Execute all functions'''

    n_threads_max = 12
    
    wkt_list, im_file, min_subgraph_length_pix, \
        node_iter, edge_iter, \
        min_spur_length_m, simplify_graph, \
        rdp_epsilon,\
        manually_reproject_nodes, \
        out_file, graph_dir, n_threads, verbose \
        = params

    print("im_file:", im_file)
    # print("wkt_list:", wkt_list)
    pickle_protocol = 4
    
    t0 = time.time()
    if verbose:
        print ("Running wkt_list_to_nodes_edges()...")
    node_loc_dic, edge_dic = wkt_list_to_nodes_edges(wkt_list, 
                                                     node_iter=node_iter,
                                                     edge_iter=edge_iter)
    t1 = time.time()
    if verbose:
        print ("Time to run wkt_list_to_nodes_egdes():", t1 - t0, "seconds")
    
    #print ("node_loc_dic:", node_loc_dic)
    #print ("edge_dic:", edge_dic)
    
    if verbose:
        print ("Creating G...")
    G0 = nodes_edges_to_G(node_loc_dic, edge_dic)  
    if verbose:
        print ("  len(G.nodes():", len(G0.nodes()))
        print ("  len(G.edges():", len(G0.edges()))
    #for edge_tmp in G0.edges():
    #    print ("\n 0 wtk_to_G():", edge_tmp, G0.edge[edge_tmp[0]][edge_tmp[1]])
    
    t2 = time.time()
    if verbose:
        print ("Time to run nodes_edges_to_G():", t2-t1, "seconds")
 
    # This graph will have a unique edge for each line segment, meaning that
    #  many nodes will have degree 2 and be in the middle of a long edge.

    # run clean_sub_graph() in 04_skeletonize.py?  - Nope, do it here
    # so that adding small terminals works better...
    if verbose:
        print ("Clean out short subgraphs")
    G1 = clean_sub_graphs(G0, min_length=min_subgraph_length_pix, 
                      weight='length_pix', verbose=verbose,
                      super_verbose=False)
    t3 = time.time()
    if verbose:
        print ("Time to run clean_sub_graphs():", t3-t2, "seconds")
    t3 = time.time()
    # G1 = G0

    if len(G1) == 0:
        return G1
    
    # print ("Simplifying graph")
    # G0 = ox.simplify_graph(G0.to_directed())
    # G0 = G0.to_undirected()
    # #G0 = ox.project_graph(G0)
    # #G_p_init = create_edge_linestrings(G_p_init, remove_redundant=True, verbose=False)
    # t3 = time.time()
    # print ("  len(G.nodes():", len(G0.nodes()))
    # print ("  len(G.edges():", len(G0.edges()))
    # print ("Time to run simplify graph:", t30 - t3, "seconds")
    
    #for edge_tmp in G0.edges():
    #    print ("\n 1 wtk_to_G():", edge_tmp, G0.edge[edge_tmp[0]][edge_tmp[1]])
    
    #edge_tmp = G0.edges()[5]
    #print (edge_tmp, "G0.edge props:", G0.edge[edge_tmp[0]][edge_tmp[1]])

    
    # geo coords
    if im_file:
        if verbose:
            print ("Running get_node_geo_coords()...")
        # let's not over multi-thread a multi-thread
        if n_threads > 1:
            n_threads_tmp = 1
        else:
            n_threads_tmp = n_threads_max
        G1 = get_node_geo_coords(G1, im_file, n_threads=n_threads_tmp,
                                     verbose=verbose)
        t4= time.time()
        if verbose:
            print ("Time to run get_node_geo_coords():", t4-t3, "seconds")

        if verbose:
            print ("Running get_edge_geo_coords()...")
        # let's not over multi-thread a multi-thread
        if n_threads > 1:
            n_threads_tmp = 1
        else:
            n_threads_tmp = n_threads_max
        G1 = get_edge_geo_coords(G1, im_file, n_threads=n_threads_tmp,
                                 verbose=verbose)
        t5 = time.time()
        if verbose:
            print ("Time to run get_edge_geo_coords():", t5-t4, "seconds")

        if verbose:
            print("pre projection...")
        node = list(G1.nodes())[-1]
        if verbose:
            print(node, "random node props:", G1.nodes[node])
            # print an edge
            edge_tmp = list(G1.edges())[-1]
            print(edge_tmp, "random edge props:", G1.get_edge_data(edge_tmp[0], edge_tmp[1]))

        if verbose:
            print ("projecting graph...")
        G_projected = ox.project_graph(G1)
    
        # get geom wkt (for printing/viewing purposes)
        for i,(u,v,attr_dict) in enumerate(G_projected.edges(data=True)):
            attr_dict['geometry_wkt'] = attr_dict['geometry'].wkt

        if verbose:
            print("post projection...")
            node = list(G_projected.nodes())[-1]
            print(node, "random node props:", G_projected.nodes[node])
            # print an edge
            edge_tmp = list(G_projected.edges())[-1]
            print(edge_tmp, "random edge props:", G_projected.get_edge_data(edge_tmp[0], edge_tmp[1]))

        t6 = time.time()
        if verbose:
            print ("Time to project graph:", t6-t5, "seconds")

        # simplify
        #G_simp = ox.simplify_graph(G_projected.to_directed())
        #ox.plot_graph(G_projected)
        #G1.edge[19][22]
        
        Gout = G_projected #G_simp
    
    else:
        Gout = G0

    # ###########################################################################
    # # remove short edges?
    # # this is done in 04_skeletonize.remove_small_terminal()
    # t31 = time.time()
    # Gout = remove_short_edges(Gout, min_spur_length_m=min_spur_length_m)
    # t32 = time.time()
    # print("Time to remove_short_edges():", t32 - t31, "seconds")
    # ###########################################################################

    if simplify_graph:
        if verbose:
            print("Simplifying graph")
        t7 = time.time()
        # 'geometry' tag breaks simplify, so maket it a wkt
        for i,(u,v,attr_dict) in enumerate(G_projected.edges(data=True)):
            if 'geometry' in attr_dict.keys():
                attr_dict['geometry'] = attr_dict['geometry'].wkt
                
        G0 = ox.simplify_graph(Gout.to_directed())
        G0 = G0.to_undirected()
        # print("G0")
        # node = list(G0.nodes())[-1]
        # print(node, "random node props:", G0.nodes[node])
        
        #Gout = G0
        # reprojecting graph screws up lat lon, so convert to string?
        Gout = ox.project_graph(G0)
        
        # print("Gout")
        # node = list(Gout.nodes())[-1]
        # print(node, "random node props:", Gout.nodes[node])

        if verbose:
            print("post simplify...")
            node = list(Gout.nodes())[-1]
            print(node, "random node props:", Gout.nodes[node])
            # print an edge
            edge_tmp = list(Gout.edges())[-1]
            print(edge_tmp, "random edge props:", Gout.get_edge_data(edge_tmp[0], edge_tmp[1]))


        t8 = time.time()
        if verbose:
            print("Time to run simplify graph:", t8-t7, "seconds")
        # When the simplify funciton combines edges, it concats multiple
        #  edge properties into a list.  This means that 'geometry_pix' is now
        #  a list of geoms.  Convert this to a linestring with
        #   shaply.ops.linemergeconcats

        # BUG, GOOF, ERROR IN OSMNX PROJECT, SO NEED TO MANUALLY SET X, Y FOR NODES!!??
        if manually_reproject_nodes:
            # make sure geometry is utm for nodes?
            for i, (n, attr_dict) in enumerate(Gout.nodes(data=True)):
                attr_dict['x'] = attr_dict['utm_east']
                attr_dict['y'] = attr_dict['utm_north']         

    # if simplify_graph:
    #     print ("Simplifying graph")
    #     t7 = time.time()
    #     G0 = ox.simplify_graph(Gout.to_directed())
    #     Gout = G0.to_undirected()
    #     #Gout = ox.project_graph(G0)
        
    #     t8 = time.time()
    #     print ("Time to run simplify graph:", t8-t7, "seconds")
    #     # When the simplify funciton combines edges, it concats multiple
    #     #  edge properties into a list.  This means that 'geometry_pix' is now
    #     #  a list of geoms.  Convert this to a linestring with 
    #     #   shaply.ops.linemergeconcats 
                
        if verbose:
            print ("Merge 'geometry' linestrings...")
        keys_tmp = ['geometry_wkt', 'geometry_pix', 'geometry_latlon_wkt',
                    'geometry_utm_wkt']
        for key_tmp in keys_tmp:
            if verbose:
                print ("Merge", key_tmp, "...")
            for i,(u,v,attr_dict) in enumerate(Gout.edges(data=True)):
                if key_tmp not in attr_dict.keys():
                    continue
                
                if (i % 10000) == 0:
                    print (i, u , v)
                geom = attr_dict[key_tmp]
                #print (i, u, v, "geom:", geom)
                #print ("  type(geom):", type(geom))
                
                if type(geom) == list:
                    # check if the list items are wkt strings, if so, create
                    #   linestrigs
                    if (type(geom[0]) == str):# or (type(geom_pix[0]) == unicode):
                        geom = [shapely.wkt.loads(ztmp) for ztmp in geom]
                    # merge geoms
                    #geom = shapely.ops.linemerge(geom)
                    #attr_dict[key_tmp] =  geom
                    geom_out = shapely.ops.linemerge(geom)
                    # attr_dict[key_tmp] = shapely.ops.linemerge(geom)
                elif type(geom) == str:
                    geom_out = shapely.wkt.loads(geom)
                    # attr_dict[key_tmp] = shapely.wkt.loads(geom)
                else:
                    geom_out = geom
                    
                # now straighten edge with rdp
                if rdp_epsilon > 0:
                    if verbose and ((i % 10000) == 0):
                        print("  Applying rdp...")
                    coords = list(geom_out.coords)
                    new_coords = rdp.rdp(coords, epsilon=rdp_epsilon)
                    geom_out_rdp = LineString(new_coords)
                    geom_out_final = geom_out_rdp
                else:
                    geom_out_final = geom_out
                    
                len_out = geom_out_final.length
                
                # updata edge properties
                attr_dict[key_tmp] = geom_out_final
                
                # update length
                if key_tmp == 'geometry_pix':
                    attr_dict['length_pix'] = len_out
                if key_tmp == 'geometry_utm_wkt':
                    attr_dict['length_utm'] = len_out  
                    
        # assign 'geometry' tag to geometry_wkt
        # !! assign 'geometry' tag to geometry_utm_wkt
        key_tmp = 'geometry_wkt'   # 'geometry_utm_wkt'
        for i,(u,v,attr_dict) in enumerate(Gout.edges(data=True)):
            if verbose and ((i % 10000) == 0):
                print ("Create 'geometry' field in edges...")
            line = attr_dict['geometry_utm_wkt']       
            if type(line) == str:# or type(line) == unicode:
                attr_dict['geometry'] = shapely.wkt.loads(line) 
            else:
                attr_dict['geometry'] = attr_dict[key_tmp]  
            attr_dict['geometry_wkt'] = attr_dict['geometry'].wkt
            
            # set length
            attr_dict['length'] = attr_dict['geometry'].length
            
            # update wkt_pix?
            #print ("attr_dict['geometry_pix':", attr_dict['geometry_pix'])
            attr_dict['wkt_pix'] = attr_dict['geometry_pix'].wkt
        
            # update 'length_pix'
            attr_dict['length_pix'] = np.sum([attr_dict['length_pix']])
            
        # Gout = ox.project_graph(Gout) 
    
    # print a random node and edge
    if verbose:
        node_tmp = list(Gout.nodes())[-1]
        print(node_tmp, "random node props:", Gout.nodes[node_tmp])
        # print an edge
        edge_tmp = list(Gout.edges())[-1]
        print("random edge props for edge:", edge_tmp, " = ",
              Gout.edges[edge_tmp[0], edge_tmp[1], 0]) 
        
    # get a few stats (and set to graph properties)
    if verbose:
        logger1.info("Number of nodes: {}".format(len(Gout.nodes())))
        logger1.info("Number of edges: {}".format(len(Gout.edges())))
    #print ("Number of nodes:", len(Gout.nodes()))
    #print ("Number of edges:", len(Gout.edges()))
    Gout.graph['N_nodes'] = len(Gout.nodes())
    Gout.graph['N_edges'] = len(Gout.edges())
    
    # get total length of edges
    tot_meters = 0
    for i,(u,v,attr_dict) in enumerate(Gout.edges(data=True)):
        tot_meters  += attr_dict['length'] 
    if verbose:
        print ("Length of edges (km):", tot_meters/1000)
    Gout.graph['Tot_edge_km'] = tot_meters/1000

    if verbose:
        print ("G.graph:", Gout.graph)

    # save     
    if len(Gout.nodes()) == 0:
        nx.write_gpickle(Gout, out_file, protocol=pickle_protocol)
        return
    
    # # print a node
    # node = list(Gout.nodes())[-1]
    # print (node, "random node props:", Gout.nodes[node])
    # # print an edge
    # edge_tmp = list(Gout.edges())[-1]
    # #print (edge_tmp, "random edge props:", G.edges([edge_tmp[0], edge_tmp[1]])) #G.edge[edge_tmp[0]][edge_tmp[1]])
    # print (edge_tmp, "random edge props:", Gout.get_edge_data(edge_tmp[0], edge_tmp[1]))

    # save graph
    if verbose:
        logger1.info("Saving graph to directory: {}".format(graph_dir))
    #print ("Saving graph to directory:", graph_dir)
    nx.write_gpickle(Gout, out_file, protocol=pickle_protocol)
    
    # # save shapefile as well?
    # if save_shapefiles:
    #     logger1.info("Saving shapefile to directory: {}".format(graph_dir))
    #     try:
    #         ox.save_graph_shapefile(G, filename=image_id.split('.')[0] , folder=graph_dir, encoding='utf-8')
    #     except:
    #         print("Cannot save shapefile...")
    #     #out_file2 = os.path.join(graph_dir, image_id.split('.')[0] + '.graphml')
    #     #ox.save_graphml(G, image_id.split('.')[0] + '.graphml', folder=graph_dir)
    #
    # # plot, if desired
    # if make_plots:
    #     print ("Plotting graph...")
    #     outfile_plot = os.path.join(graph_dir, image_id)
    #     print ("outfile_plot:", outfile_plot)
    #     ox.plot_graph(G, fig_height=9, fig_width=9,
    #                   #save=True, filename=outfile_plot, margin=0.01)
    #                   )
    #     #plt.tight_layout()
    #     plt.savefig(outfile_plot, dpi=400)
            
    t7 = time.time()
    if verbose:
        print ("Total time to run wkt_to_G():", t7-t0, "seconds")
    
    return # Gout
Beispiel #28
0
def simple_link_mapper(graph, strict=True):
    """
    CREDIT: https://github.com/gboeing/osmnx/blob/master/osmnx/simplify.py

    ------- modified for different functionality -------

    The default graph extracted has lots of links due to every bend in the road
    being classified as a link. Due to graph having lots of links (and the map matcher requiring it to do so),
    we need a way to map these smaller links to their simplified ones so we can
    model the longer roads as desired. Helper function.

    Returns a dictionary unsimplified edges to their corresponding simplified links
    as well as the proportion (lengths) of those simplified links they represent.

    Parameters:
    ----------
    graph (networkx multidigraph)
    strict (bool): if False, allow nodes to be end points even if they fail all other rules
                   but have edges with different OSM IDs
    Returns:
    -------
    link_mapper (dictionary): Dictionary that maps unsimplified edges to their corresponding simplified links
                              as well as the proportion (lengths) of those simplified links they represent.
    """

    # first identify all the nodes that are endpoints
    endpoints = set([
        node for node in graph.nodes()
        if ox.is_endpoint(graph, node, strict=strict)
    ])
    paths_to_simplify = []
    # for each endpoint node, look at each of its successor nodes
    for node in endpoints:
        for successor in graph.successors(node):
            if successor not in endpoints:
                # if the successor is not an endpoint, build a path from the
                # endpoint node to the next endpoint node
                try:
                    path = ox.build_path(graph,
                                         successor,
                                         endpoints,
                                         path=[node, successor])
                    paths_to_simplify.append(path)
                except RuntimeError:
                    continue
            else:
                # just add node, successor into paths to simplify anyways (so it get's added to link_mapper later)
                paths_to_simplify.append([node, successor])
    # Now we have a list of paths to simplify
    # we will now use the edges of a pre-simplified graph for comparison
    simplified_graph = ox.simplify_graph(graph, strict=True)
    simple_edge_data = return_edge_data(simplified_graph)
    #also get the edge data for normal graph
    edge_data = return_edge_data(graph)
    link_mapper = {}
    # now iterate through the paths to simplify
    for path in paths_to_simplify:
        # simplified edge corresponds to first and last of path
        simple_edge = get_edge_name(path[0], path[-1])
        simple_edge_length = simple_edge_data[simple_edge]['length']
        # now iterate through interstitial nodes
        for u, v in zip(path[:-1], path[1:]):
            edge_name_1 = get_edge_name(u, v)
            # now take into account other direction too
            edge_name_2 = get_edge_name(v, u)
            # now find what proportion of simple link length this link is
            proportion = edge_data[edge_name_1]['length'] / simple_edge_length
            link_mapper[edge_name_1] = {
                'simple_link': simple_edge,
                'proportion': proportion
            }
            link_mapper[edge_name_2] = {
                'simple_link': simple_edge,
                'proportion': proportion
            }

    return link_mapper
                         network_type='bike')
ox.plot_graph(G2,
              node_zorder=2,
              node_size=10,
              node_alpha=1,
              node_color='r',
              bgcolor='w',
              edge_linewidth=0.2,
              use_geom=True,
              axis_off=False,
              show=False,
              close=False)
ox.graph_to_gdfs(G2, nodes=False)
G2_proj = ox.project_graph(G2)
G3 = ox.consolidate_intersections(G2_proj, tolerance=10, rebuild_graph=True)
G4 = ox.simplify_graph(G3.copy())
ox.plot_graph(G3,
              node_zorder=2,
              node_size=10,
              node_alpha=1,
              node_color='r',
              bgcolor='w',
              edge_linewidth=0.2,
              use_geom=True,
              axis_off=False,
              show=False,
              close=False)

gdf_edge_sample = ox.graph_to_gdfs(G3, nodes=False)
gdf_edge_sample.groupby(['u', 'v']).count()
    def network_dfs(self):
        g = self.graph_latlon
        if not self.strict:
            g = ox.simplify_graph(g, strict=self.strict)
        g = ox.add_edge_bearings(g, precision=1)
        n, e = ox.graph_to_gdfs(g)
        e = e.reset_index()  # Method graph_to_gdfs changed to multiindex df
        network_edges, network_nodes_small = dbl_cleaning(ndf=n, edf=e)
        network_edges = network_edges.join(network_nodes_small, on='u')
        network_edges = network_edges.rename(columns={
            'u': 'n1',
            'y': 'lat1',
            'x': 'lon1'
        })
        network_edges = network_edges.join(network_nodes_small, on='v')
        network_edges = network_edges.rename(columns={
            'v': 'n2',
            'y': 'lat2',
            'x': 'lon2'
        })
        x1, y1 = zip(
            *project_point(list(zip(network_edges.lon1, network_edges.lat1))))
        x2, y2 = zip(
            *project_point(list(zip(network_edges.lon2, network_edges.lat2))))
        network_edges = network_edges.assign(x1=x1, y1=y1, x2=x2, y2=y2)
        network_edges['edge'] = list(
            zip(network_edges['n1'].values, network_edges['n2'].values))
        network_edges.reset_index(
            inplace=True
        )  # From hereon the unique index of an edge is just its position in df
        network_edges = network_edges.rename(columns={'index': '_id'})
        self.graph_latlon = g
        self.graph_xy = ox.project_graph(self.graph_latlon)
        self.network_edges = network_edges
        self._get_network_nodes(network_edges)
        # link node_tags to specific edge, osmid not unique over edges after simplification
        nearest = ox.get_nearest_edges(self.graph_xy,
                                       self.node_tags.x.to_list(),
                                       self.node_tags.y.to_list(),
                                       method='kdtree',
                                       dist=1)
        n1, n2, _ = zip(*nearest)
        test_b1 = network_edges[['_id', 'edge',
                                 'bearing']][network_edges.edge.isin(
                                     list(zip(n1, n2)))].values
        test_b2 = network_edges[['_id', 'edge',
                                 'bearing']][network_edges.edge.isin(
                                     list(zip(n2, n1)))].values
        self.node_tags['edge'] = [ij for ij in zip(n1, n2)]
        self.node_tags.reset_index(inplace=True)
        self.node_tags = self.node_tags.merge(
            self.network_edges[['edge', 'bearing']],
            on='edge',
            suffixes=('', '_edge'))
        diff_b = abs(self.node_tags['bearing'] -
                     self.node_tags['bearing_edge'])
        for i, j in diff_b.iteritems():
            if (j > 45) and not self.node_tags.junction[i]:
                self.node_tags.at[i,
                                  'edge'] = (self.node_tags.at[i, 'edge'][1],
                                             self.node_tags.at[i, 'edge'][0])
        self.node_tags.drop('bearing_edge', axis=1, inplace=True)
        self.node_tags = self.node_tags.merge(
            self.network_edges[['_id', 'edge', 'bearing']],
            on='edge',
            suffixes=('', '_edge'))
        diff_b2 = abs(self.node_tags['bearing'] -
                      self.node_tags['bearing_edge'])
        breakpoint()
        # check if nearest edge is in right direction, problem with two way streets

        self.node_tags.set_index('index', inplace=True)
        self.node_tags.sort_index(inplace=True)
Beispiel #31
0
def pedestrians_first(boundaries, 
                      id_code,
                      name,
                      folder_name='', 
                      buffer_dist=100,#m
                      headway_threshold=10,#min
                      to_test = [
                           'healthcare',
                           'schools',
                           'h+s',
                           'libraries',
                           'carfree',
                           'blocks',
                           'density',
                           'transit',
                           'pnb',
                           #'special',
                           ],
                      distances = { #network buffers, in meters
                            'healthcare': 1000,
                            'schools': 1000,
                            'libraries': 1000,
                            'transit': 500,
                            'special': 500,
                            'pnb': 250,
                            },
                      overpass = False,
                      patch_length = 5, #km
                      boundary_buffer = 0, #km
                      blocks_simplification = 15, #m
                      gtfs_files = [],
                      ):    
    dt = datetime.datetime.now()
    logger = logging.getLogger()
    logger.setLevel(logging.CRITICAL)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

    fh = logging.FileHandler('log_filename.txt')
    fh.setLevel(logging.DEBUG)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(formatter)
    logger.addHandler(ch)
    
    useful_tags = ox.settings.useful_tags_way + ['cycleway', 'cycleway:left', 'cycleway:right']
    ox.config(use_cache=True, log_console=True, useful_tags_way=useful_tags)
    
    if folder_name != '' and not folder_name[-1:] == '/':
        folder_name += '/'
    
    if boundary_buffer > 0:
        bound_latlon = gpd.GeoDataFrame(geometry = [boundaries])
        bound_latlon.crs = {'init':'epsg:4326'}
        longitude = round(numpy.mean(bound_latlon.geometry.centroid.x),10)
        utm_zone = int(math.floor((longitude + 180) / 6) + 1)
        utm_crs = '+proj=utm +zone={} +ellps=WGS84 +datum=WGS84 +units=m +no_defs'.format(utm_zone)
        bound_utm = bound_latlon.to_crs(utm_crs)
        bound_utm.geometry = bound_utm.geometry.buffer(boundary_buffer*1000)
        bound_latlon = bound_utm.to_crs(epsg=4326)
        boundaries = bound_latlon.geometry.unary_union
    
    bbox = boundaries.bounds
    
    crs = None 
    
    if type(boundaries) == shapely.geometry.multipolygon.MultiPolygon:
        patches = []
        for poly in list(boundaries):
            patches += make_patches(poly, patch_length=patch_length)
    else:
        patches = make_patches(boundaries, patch_length=patch_length)
    
    longitude_factor = 0.00898 # degrees per km
    longitude_factor_m = 0.00898 / 1000 # degrees per m
    latitude_factor = (math.cos(abs(boundaries.bounds[1])*0.0174533))/111.319
    latitude_factor_m = latitude_factor / 1000
    
    print('Evaluating Pedestrians First indicators in',name)
    print('Measuring',str(to_test))
    
    quilt_isochrone_polys = {}
    quilt_center_nodes = {}
    for service in to_test:
        quilt_isochrone_polys[service] = False
        quilt_center_nodes[service] = []
    
    patch_times = []
    
    all_coords={}
    
    testing_services = []
    for service in ['healthcare', 'schools', 'libraries']:
        if service in to_test:
            testing_services.append(service)
            #all_coords[service] = get_point_locations(boundaries, queries[service])
    
    if len(testing_services) > 0:
        handler = get_service_locations.ServiceHandler()
        handler.apply_file(folder_name+'/city.o5m', locations=True)
        for service in testing_services:
            all_coords[service] = handler.locationlist[service]
            citywide_carfree = handler.carfreelist
            
    #should I finish this?
    if 'highways' in to_test:     
        highway_filter = '["area"!~"yes"]["highway"~"motorway|trunk"]'
        G_hwys = ox.graph_from_polygon(boundaries,
                                custom_filter=highway_filter,
                                retain_all=True)
        G_hwys = ox.project_graph(G_hwys)
        edges_hwys = ox.utils_graph.graph_to_gdfs(G_hwys, nodes=False)
        edges_polyline = edges_hwys.geometry.unary_union
        increment_dist = 25
        distances = np.arange(0, edges_polyline.length, increment_dist)
        points = [edges_polyline.interpolate(distance) for distance in distances] + [edges_polyline.boundary[1]]
        multipoint = unary_union(points)
        #need to switch back to latlon and put in all_coords['highway']
        
    if 'special' in to_test:
        if os.path.isfile(folder_name+'/special.shp'):
            testing_services.append('special')
            special = gpd.read_file(folder_name+'/special.shp')
            all_coords['special'] = [(pt.y, pt.x) for pt in special.geometry]

    if 'transit' in to_test:
        testing_services.append('transit')
        #this approach does not let us combine OpenMobilityData files with local files.
        if len(gtfs_files) == 0:
            sources = gtfs_parser.get_feed_infos(gtfs_parser.get_relevant_locs(bbox))
            #note! This doesn't reflect a buffered boundary if boundary_buffer > 0
            transit_stop_sets = gtfs_parser.count_all_sources(sources, 
                                                              source_type = 'openmobilitydata',
                                                              headwaylim = headway_threshold * 2)
        else:
            transit_stop_sets = gtfs_parser.count_all_sources(gtfs_files, 
                                                              source_type = 'local_files',
                                                              headwaylim = headway_threshold * 2)
            
    if 'pnb' in to_test:
        testing_services.append('pnb')
        
        
    if len(to_test) > 0 and to_test != ["blocks"]:
        for p_idx, patch in enumerate(patches):
            try:
                patch_start = datetime.datetime.now()
                
                unbuffered_patch = patch
                
                max_service_dist_km = max(distances.values())/1000
                
                patch = shapely.geometry.box(
                        patch.bounds[0] - (max_service_dist_km * longitude_factor),
                        patch.bounds[1] - (max_service_dist_km * latitude_factor),
                        patch.bounds[2] + (max_service_dist_km * longitude_factor),
                        patch.bounds[3] + (max_service_dist_km * latitude_factor)
                        )
                        
                
                walk_filter = ('["area"!~"yes"]["highway"!~"link|motor'
                               '|proposed|construction|abandoned'
                               '|platform|raceway"]'
                               '["service"!~"parking_aisle|driveway"]'
                               '["foot"!~"no"]["service"!~"private"]'
                               '{}').format(ox.settings.default_access)
                
                if overpass:
                    G = ox.graph_from_polygon(patch, 
                                              custom_filter=walk_filter, 
                                              simplify=False, 
                                              retain_all=True)
                else:
                    boundingarg = '-b='
                    boundingarg += str(patch.bounds[0])+','
                    boundingarg += str(patch.bounds[1])+','
                    boundingarg += str(patch.bounds[2])+','
                    boundingarg += str(patch.bounds[3])
                    subprocess.check_call(['osmconvert',
                                           str(folder_name)+'/citywalk.o5m',
                                           boundingarg,
                                           #'--complete-ways',
                                           '--drop-broken-refs',
                                           '-o=patch.osm'])
                    G = ox.graph_from_xml('patch.osm', 
                                           simplify=False, retain_all=True)
                    os.remove('patch.osm')
                    if 'pnb' in to_test:
                        subprocess.check_call(['osmconvert',
                                           str(folder_name)+'/cityhighways.o5m',
                                           boundingarg,
                                           #'--complete-ways',
                                           '--drop-broken-refs',
                                           '-o=allhwyspatch.osm'])
                        G_allhwys = ox.graph_from_xml('allhwyspatch.osm', 
                                           simplify=False, retain_all=True)
                        os.remove('allhwyspatch.osm')
                        
                
                G.remove_nodes_from(list(nx.isolates(G)))
                G_allhwys.remove_nodes_from(list(nx.isolates(G_allhwys)))
                
                simple_G = ox.simplify_graph(G)
                center_nodes = {}
                for service in all_coords.keys():
                    if service in ['healthcare','schools','libraries','special']:
                        center_nodes[service] = []
                        for coord in all_coords[service]:
                            lat = coord[0]
                            lon = coord[1]
                            if unbuffered_patch.bounds[0] < lon < unbuffered_patch.bounds[2] and unbuffered_patch.bounds[1] < lat < unbuffered_patch.bounds[3]:
                                point = shapely.geometry.Point(lon,lat)
                                nearest = ox.get_nearest_node(simple_G, coord)
                                if not nearest in center_nodes[service]:    
                                    center_nodes[service].append(nearest)
                
                if 'pnb' in to_test:
                    center_nodes['pnb'] = []
                    allhwys_gdf = ox.graph_to_gdfs(G_allhwys, nodes=False)
                    print(allhwys_gdf.columns)
                    waytypes = []
                    if 'highway' in allhwys_gdf.columns:
                        waytypes.append(allhwys_gdf[allhwys_gdf['highway'] == 'cycleway'])
                    if 'cycleway' in allhwys_gdf.columns:
                        waytypes.append(allhwys_gdf[allhwys_gdf['cycleway'] == 'track'])
                    if 'cycleway:left' in allhwys_gdf.columns:
                        waytypes.append(allhwys_gdf[allhwys_gdf['cycleway:left'] == 'track'])
                    if 'cycleway:right' in allhwys_gdf.columns:
                        waytypes.append(allhwys_gdf[allhwys_gdf['cycleway:right'] == 'track'])
                    cycletracknodes = []
                    for waytype in waytypes:
                        for edge in waytype.index:
                            if not edge[0] in cycletracknodes:
                                cycletracknodes.append(edge[0])
                            if not edge[1] in cycletracknodes:
                                cycletracknodes.append(edge[1])
                    for node in cycletracknodes:
                        if node in simple_G.nodes:
                            center_nodes['pnb'].append(node)
                
                if 'transit' in to_test:
                    center_nodes['transit'] = []
                    transit_centers = {}
                    for service_idx, service in enumerate(transit_stop_sets):
                        for stop_id in service.keys():
                            lat = float(service[stop_id][1])
                            lon = float(service[stop_id][2])
                            headway = float(service[stop_id][0])
                            if unbuffered_patch.bounds[0] < lon < unbuffered_patch.bounds[2] and unbuffered_patch.bounds[1] < lat < unbuffered_patch.bounds[3]:
                                center_node = ox.get_nearest_node(simple_G, (lat, lon))
                                if center_node not in transit_centers:
                                    transit_centers[center_node] = {service_idx : headway} #store the headway value
                                elif service_idx not in transit_centers[center_node].keys():
                                    transit_centers[center_node][service_idx] = headway
                                elif headway < transit_centers[center_node][service_idx]:
                                    transit_centers[center_node][service_idx] = headway
                    for center_node in transit_centers.keys():
                        if len(transit_centers[center_node]) > 0:
                            inv_headway = 0
                            min_hw = 100
                            for service_idx in transit_centers[center_node].keys():
                                inv_headway += 1 / transit_centers[center_node][service_idx]
                                if transit_centers[center_node][service_idx] < min_hw:
                                    min_hw = transit_centers[center_node][service_idx]
                            headway = 1 / inv_headway
                            if headway <= headway_threshold:
                                center_nodes['transit'].append(center_node)
                                
                
                
                
                
                # Project Graph
                if not crs: #this only runs once, crs is invariable over patches
                    G = ox.project_graph(G)
                    crs = G.graph['crs'] 
                else:
                    G = ox.project_graph(G, to_crs=crs)
                G = ox.simplify_graph(G)
                
                isochrone_polys = {}
                failures = {}
                for service in to_test:
                    failures[service] = 0
                
                
                # Get polygons
                for service in testing_services:
                    isochrone_polys[service], fails = isochrones.make_iso_polys(G, center_nodes[service], distance=distances[service], edge_buff=buffer_dist)
                    failures[service] += fails
                    
                for service in isochrone_polys.keys():
                    if service not in quilt_isochrone_polys.keys() or not quilt_isochrone_polys[service]:
                        quilt_isochrone_polys[service] = isochrone_polys[service]
                    elif isochrone_polys[service]:
                        quilt_isochrone_polys[service] = shapely.ops.cascaded_union([quilt_isochrone_polys[service],isochrone_polys[service]])
                for service in center_nodes.keys():
                    quilt_center_nodes[service] = quilt_center_nodes[service] + center_nodes[service]
                
                patch_time = datetime.datetime.now() - patch_start
                    
                print("finished patch #",p_idx,'out of', len(patches),"in",str(patch_time))
                patch_times.append(patch_time)
            except ox._errors.EmptyOverpassResponse:
                pass
            except ValueError:
                pass #sorry 
            #except:
            #    print("GOT SOME ERROR FOR PATCH", p_idx)
            # except ValueError:
            #     print('ValueError')
            #     now = str(datetime.datetime.now())
            #     with open('error'+now+'.txt','w') as errout:
            #         traceback.print_exc(limit=3,file=errout)
            #     print('saved to error'+now+'.txt')
    
    #epsg = 32600+int(crs.split(' ')[1].split('=')[1]) #This is wild -- 
    #osmnx seems to just give all data in northern-hemisphere format
    #Sorry about the stupid parsing of the projection definition, I'm lazy 
    
    results = {'name':name,'id_code':id_code}
    
    if not os.path.exists(folder_name):
        os.makedirs(folder_name)
     
    boundaries_latlon = gpd.GeoDataFrame(geometry=[boundaries])
    boundaries_latlon.crs = {'init':'epsg:4326'}
    try:
        boundaries_utm = boundaries_latlon.to_crs(crs)
    except ValueError:
        longitude = round(numpy.mean(boundaries_latlon.geometry.centroid.x),10)
        utm_zone = int(math.floor((longitude + 180) / 6) + 1)
        utm_crs = '+proj=utm +zone={} +ellps=WGS84 +datum=WGS84 +units=m +no_defs'.format(utm_zone)
        crs = utm_crs
        boundaries_utm = boundaries_latlon.to_crs(crs)
        
    stats = rasterstats.zonal_stats(boundaries_latlon, 'pop_dens.tif', stats=['sum'])           
    total_pop = stats[0]['sum'] 
    
    for service in testing_services:
        if quilt_isochrone_polys[service]:
            service_utm = gpd.GeoDataFrame(geometry = [quilt_isochrone_polys[service]])
            service_utm.crs = crs#{'init':'epsg:'+str(epsg)}
            service_utm.geometry = service_utm.geometry.simplify(15) #maybe this should be after the population calculation
            service_utm = gpd.overlay(service_utm ,boundaries_utm, how='intersection')
            service_latlon = service_utm.to_crs(epsg=4326)
            service_latlon.to_file(folder_name+service+'latlon'+'.geojson', driver='GeoJSON')
            
            stats = rasterstats.zonal_stats(service_latlon, 'pop_dens.tif', stats=['sum'])           
            total_PNS = stats[0]['sum']
            print("\n")
            print('Total People Near Service for', service, ":", total_PNS)
            print(100*total_PNS/total_pop,"% of",total_pop)
            results[service] = total_PNS / total_pop
        else:
            print ('NO SERVICE FOR', service)
            results[service] = 0
    
    if 'carfree' in to_test:
        print("getting carfree")
        if citywide_carfree:
            carfree_latlon = gpd.GeoDataFrame(geometry = citywide_carfree)
            #just a latlon list of points
            carfree_latlon.crs = {'init':'epsg:4326'}
            carfree_utm = carfree_latlon.to_crs(crs)
            carfree_utm.geometry = carfree_utm.geometry.buffer(100)
            #this is the analysis, the 100m buffer
            carfree_utm = gpd.GeoDataFrame(geometry = [shapely.ops.cascaded_union(carfree_utm.geometry)])
            carfree_utm.geometry = carfree_utm.geometry.simplify(10)
            carfree_utm = gpd.overlay(carfree_utm ,boundaries_utm, how='intersection')
            carfree_utm.crs = crs
            carfree_latlon = carfree_utm.to_crs('epsg:4326')
            
            stats = rasterstats.zonal_stats(carfree_latlon, 'pop_dens.tif', stats=['sum'])
            total_carfree = stats[0]['sum']
            print("\n")
            print('Total People Near Service for carfree', ":", total_carfree)
            print(100*total_carfree/total_pop,"% of",total_pop)
            results['carfree'] = total_carfree / total_pop
            
            carfree_latlon = carfree_utm.to_crs('epsg:4326')
            carfree_latlon.to_file(folder_name+'carfreelatlon'+'.geojson', driver='GeoJSON')
        else:
            print ('NO SERVICE FOR carfree')
            results['carfree'] = 0
            
    
    if 'h+s' in to_test:
        if quilt_isochrone_polys['healthcare'] and quilt_isochrone_polys['schools']:
            service = 'h+s'
            intersect = quilt_isochrone_polys['healthcare'].intersection(quilt_isochrone_polys['schools'])
            if type(intersect) == shapely.geometry.collection.GeometryCollection:
                intersect = [obj for obj in intersect if type(obj) == shapely.geometry.polygon.Polygon]
                intersect = shapely.geometry.MultiPolygon(intersect)
            hs_utm = gpd.GeoDataFrame(geometry = [intersect])
            hs_utm.crs = crs#{'init':'epsg:'+str(epsg)} #maybe this should be after the population calculation
            if hs_utm.geometry.area.sum() != 0:
                hs_utm = gpd.overlay(hs_utm ,boundaries_utm, how='intersection')
                hs_utm.geometry = hs_utm.geometry.simplify(15)
                hs_latlon = hs_utm.to_crs(epsg=4326)
                hs_latlon.to_file(folder_name+service+'latlon'+'.geojson', driver='GeoJSON')
                stats = rasterstats.zonal_stats(hs_latlon, 'pop_dens.tif', stats=['sum'])
                
                total_PNS = stats[0]['sum']
                print("\n")
                print('Total People Near Service for', service, ":", total_PNS)
                print(100*total_PNS/total_pop,"% of",total_pop)
                results[service] = total_PNS / total_pop
            else:
                print ('NO SERVICE FOR h+s')
                results['h+s'] = 0
        else:
            print ('NO SERVICE FOR h+s')
            results['h+s'] = 0
    
    if 'density' in to_test:
        density = rasterstats.zonal_stats(boundaries, 
                                'pop_dens.tif', 
                                stats = [],
                                add_stats={'weighted': weighted_pop_density}
                                )[0]['weighted']
        results['density'] = density / 0.0625 #km^2 / pixel
        print('weighted pop density', results['density'])
        with rasterio.open('pop_dens.tif') as dataset:
            out_image, out_transform = rasterio.mask.mask(dataset, [boundaries], crop=True)
            out_meta = dataset.meta
            out_meta.update({"driver": "GTiff",
                 "height": out_image.shape[1],
                 "width": out_image.shape[2],
                 "transform": out_transform})
        with rasterio.open(folder_name+"pop_dens.tif", "w", **out_meta) as dest:
            dest.write(out_image)
            
    #garbage collection
    quilt_isochrone_polys = None
    isochrone_polys = None
    out_image = None
    dest = None
    dataset = None
    a = None
    b = None
    import gc 
    gc.collect()
    
    if 'blocks' in to_test:
        print("getting blocks")
        
        patches = make_patches(boundaries, patch_length=patch_length)
        print ("cut", len(list(patches)),"patches for block size in",name)
        
        outblocks = []
        block_counts = []
        for n, patch in enumerate(patches):
            print("patch"+str(n)+" of "+str(len(patches)) )
            unbuffered_patch = gpd.GeoSeries(patch, crs={'init':'epsg:4326'})
            unbuffered_patch = unbuffered_patch.to_crs(crs)[0]
            
            
            buffer_dist = 1
            
            patch = shapely.geometry.box(
                    patch.bounds[0] - (buffer_dist * longitude_factor),
                    patch.bounds[1] - (buffer_dist * latitude_factor),
                    patch.bounds[2] + (buffer_dist * longitude_factor),
                    patch.bounds[3] + (buffer_dist * latitude_factor)
                    )
            
            if overpass:
                G = ox.graph_from_polygon(patch, custom_filter=walk_filter, simplify=False, retain_all=True)
            else:
                boundingarg = '-b='
                boundingarg += str(patch.bounds[0])+','
                boundingarg += str(patch.bounds[1])+','
                boundingarg += str(patch.bounds[2])+','
                boundingarg += str(patch.bounds[3])
                subprocess.check_call(['osmconvert',
                                       folder_name+'/citywalk.o5m',
                                       boundingarg,
                                       #'--complete-ways',
                                       '--drop-broken-refs',
                                       '-o=patch.osm'])
                try:
                    G = ox.graph_from_xml('patch.osm', simplify=False, retain_all=True)
                except:
                    G = False
            
            if G:
                try:
                    G = ox.project_graph(G, to_crs=crs)
                    G = ox.simplify_graph(G)
                    
                    streets = ox.utils_graph.graph_to_gdfs(G, nodes = False)
                    
                    if not streets.empty:
                        streets = shapely.geometry.MultiLineString(list(streets.geometry))
                        merged = shapely.ops.linemerge(streets)
                        if merged:
                            borders = shapely.ops.unary_union(merged)
                            blocks = list(shapely.ops.polygonize(borders))
                            all_blocks = []
                            selected_areas = []
                            for block in blocks:
                                if 500 < block.area: #< 200000000:
                                    if block.interiors:
                                        block = shapely.geometry.Polygon(block.exterior)
                                    if block.centroid.within(unbuffered_patch):
                                        area = round(block.area, 3)
                                        perim = round(block.length, 3)
                                        lemgth = round((perim * perim) / area, 3)
                                        if blocks_simplification:
                                            block = block.simplify(blocks_simplification)
                                        all_blocks.append((block, area, perim, lemgth))
                                        if (lemgth < 50) and (1000 < area < 1000000):
                                            selected_areas.append(area)
                            outblocks += all_blocks
                            block_counts.append(len(all_blocks))
                        else:
                            block_counts.append(0)
                            print('not merged!')
                    else:
                        block_counts.append(0)
                except:
                    print('Hawassa Error')
                    block_counts.append(0)
            else:
                block_counts.append(0)
        
        #export            
        
        patch_densities = gpd.GeoDataFrame(geometry = list(patches))
        patch_densities['block_count'] = block_counts
        patch_densities.crs = {'init':'epsg:4326'}
        patch_densities_utm = patch_densities.to_crs(crs)
        patch_densities_utm['density'] = patch_densities_utm.block_count / (patch_densities_utm.area /1000000)
        patch_densities_latlon = patch_densities_utm.to_crs(epsg=4326)
        patch_densities_latlon.to_file(folder_name+'patch_densities'+'latlon'+'.geojson', driver='GeoJSON')
        
        a = gpd.GeoDataFrame(geometry=[block[0] for block in outblocks])
        a.crs = crs#{'init':'epsg:'+str(epsg)}
        a['area'] = [block[1] for block in outblocks]
        a['perim'] = [block[2] for block in outblocks]
        a['lemgth'] = [block[3] for block in outblocks]
        a['density'] = [1000000/block[1] for block in outblocks]
        b = a.to_crs(epsg=4326)
        b.to_file(folder_name+'blocks'+'latlon'+'.geojson', driver='GeoJSON')
        #b.to_file(folder_name+'blocks'+'latlon'+'.shp')
        filtered_blocks = []
        for block in outblocks:
            if block[3] < 50:
                if 1000 < block[1] < 1000000:
                    filtered_blocks.append(block)
        c = gpd.GeoDataFrame(geometry=[block[0] for block in outblocks])
        c.crs = crs#{'init':'epsg:'+str(epsg)}
        c['area'] = [block[1] for block in outblocks]
        c['perim'] = [block[2] for block in outblocks]
        c['lemgth'] = [block[3] for block in outblocks]
        try:
            blockmedian = statistics.median([block[1] for block in filtered_blocks])
            print('median block density')
            results['blockmedian_density'] = 1000000 / blockmedian
            print(results['blockmedian_density'])
        except:
            results['blockmedian_density'] = 0
            print('BLOCK MEDIAN COULD NOT BE CALCULATED')
        try:
            blockmean = statistics.mean([block[1] for block in filtered_blocks])
            print('mean block density')
            results['blockmean_density'] = 1000000 / blockmean
            print(results['blockmean_density'])
        except:
            results['blockmean_density'] = 0
            print('BLOCK MEAN COULD NOT BE CALCULATED')
        
    ft = datetime.datetime.now()
    print("total", str(ft-dt))
    results['calctime'] = str(ft-dt)
    results['total_pop'] = total_pop
    with open(folder_name+"results.json","w") as output:
        output.write(json.dumps(results))
    for file in ['city.o5m','cityhighways.o5m','citywalk.o5m']:
        if os.path.exists(folder_name+'/'+file):
            os.remove(folder_name+'/'+file)
    return results