def test_stats(): # create graph, add a new node, add bearings, project it G = ox.graph_from_point(location_point, dist=500, network_type="drive") G.add_node(0, x=location_point[1], y=location_point[0]) _ = ox.bearing.get_bearing((0, 0), (1, 1)) G = ox.add_edge_bearings(G) G_proj = ox.project_graph(G) # calculate stats cspn = ox.utils_graph.count_streets_per_node(G) stats = ox.basic_stats(G) stats = ox.basic_stats(G, area=1000) stats = ox.basic_stats(G_proj, area=1000, clean_intersects=True, tolerance=15, circuity_dist="euclidean") # calculate extended stats stats = ox.extended_stats(G, connectivity=True, anc=False, ecc=True, bc=True, cc=True) # calculate entropy Gu = ox.get_undirected(G) entropy = ox.bearing.orientation_entropy(Gu, weight="length") fig, ax = ox.bearing.plot_orientation(Gu, area=True, title="Title") fig, ax = ox.bearing.plot_orientation(Gu, ax=ax, area=False, title="Title") # test cleaning and rebuilding graph G_clean = ox.consolidate_intersections(G_proj, tolerance=10, rebuild_graph=True, dead_ends=True) G_clean = ox.consolidate_intersections(G_proj, tolerance=10, rebuild_graph=True, reconnect_edges=False) G_clean = ox.consolidate_intersections(G_proj, tolerance=10, rebuild_graph=False) # try consolidating an empty graph G = nx.MultiDiGraph(crs="epsg:4326") G_clean = ox.consolidate_intersections(G, rebuild_graph=True) G_clean = ox.consolidate_intersections(G, rebuild_graph=False)
def test_stats(): # create graph, add bearings, project it G = ox.graph_from_point(location_point, dist=500, network_type="drive") G = ox.add_edge_bearings(G) G_proj = ox.project_graph(G) # calculate stats stats = ox.basic_stats(G) stats = ox.basic_stats(G, area=1000) stats = ox.basic_stats(G_proj, area=1000, clean_intersects=True, tolerance=15, circuity_dist="euclidean") # calculate extended stats stats = ox.extended_stats(G, connectivity=True, anc=False, ecc=True, bc=True, cc=True) # test cleaning and rebuilding graph G_clean = ox.consolidate_intersections(G_proj, tolerance=10, rebuild_graph=True, dead_ends=True)
def no_dead_ends(graph): # deletes dead_end roads graph = ox.consolidate_intersections(graph, rebuild_graph=True, tolerance=1, dead_ends=False) print('Dead ends deleted..') return graph
def simplify_network(network): """ Simplifies a given road-network using OSMnx. """ network_proj = ox.project_graph(network) simplified_proj = ox.consolidate_intersections(network_proj, rebuild_graph=True, tolerance=50, dead_ends=False) simplified = ox.project_graph(simplified_proj, network.graph["crs"]) return simplified
def intersection_counts(Gup, spn, tolerance=clean_int_tol): node_ids = set(Gup.nodes) intersect_count = len([ 1 for node, count in spn.items() if (count > 1) and (node in node_ids) ]) intersect_count_clean = len( ox.consolidate_intersections(Gup, tolerance=tolerance, rebuild_graph=False, dead_ends=False)) intersect_count_clean_topo = len( ox.consolidate_intersections(Gup, tolerance=tolerance, rebuild_graph=True, reconnect_edges=False, dead_ends=False)) return intersect_count, intersect_count_clean, intersect_count_clean_topo
def no_dead_ends(graph): # deletes dead_end roads print('Deleting dead ends..') #graph = ox.project_graph(graph) graph = ox.consolidate_intersections(graph, tolerance=0.0000001, dead_ends=False) #graph = ox.consolidate_intersections(graph, rebuild_graph=True, tolerance=1, dead_ends=False) print('Dead ends deleted..') return graph
def GetNetwork(): global g_number_of_macro_nodes global g_number_of_macro_links print('downloading the target network from osm database') G = ox.graph_from_bbox(*bbox, network_type='all') # G = ox.graph_from_place(city, network_type='drive') # G_projected = ox.project_graph(G) node_attributes_df = ox.graph_to_gdfs(G, edges=False) # node_attributes_df.to_csv('node_attributes1.csv',index=False) link_attributes_df = ox.graph_to_gdfs(G, nodes=False) # link_attributes_df.to_csv('link_attributes1.csv',index=False) G_proj = ox.project_graph(G) G2 = ox.consolidate_intersections(G_proj, rebuild_graph=True, tolerance=15, dead_ends=False) node_attributes_df = ox.graph_to_gdfs(G2, edges=False) # node_attributes_df.to_csv('node_attributes2.csv',index=False) link_attributes_df = ox.graph_to_gdfs(G2, nodes=False) # link_attributes_df.to_csv('link_attributes2.csv',index=False) print('generating macro nodes') node_attributes_df = ox.graph_to_gdfs(G, edges=False) node_df_index_list = node_attributes_df.index for node_index in node_df_index_list: node = MacroNode() node.original_node_id = node_attributes_df.loc[node_index, 'osmid'] if new_node_id_starting_from_one: node.node_id = g_number_of_macro_nodes + 1 g_original_node_id_to_new_node_id_dict[ node.original_node_id] = node.node_id else: node.node_id = node.original_node_id node.node_seq_no = g_number_of_macro_nodes node.x_coord = node_attributes_df.loc[node_index, 'x'] node.y_coord = node_attributes_df.loc[node_index, 'y'] node_type = node_attributes_df.loc[node_index, 'highway'] node.node_type = node_type if isinstance(node_type, str) else '' node.geometry = node_attributes_df.loc[node_index, 'geometry'] g_macro_node_list.append(node) g_node_id_to_seq_no_dict[node.node_id] = node.node_seq_no g_number_of_macro_nodes += 1 print('generating macro links') link_attributes_df = ox.graph_to_gdfs(G, nodes=False) link_attributes_df['name'] = link_attributes_df.apply( lambda x: x['name'][0] if isinstance(x['name'], list) else x['name'], axis=1) link_attributes_df['highway'] = link_attributes_df.apply( lambda x: x['highway'][0] if isinstance(x['highway'], list) else x['highway'], axis=1) link_attributes_df['osmid'] = link_attributes_df.apply( lambda x: x['osmid'][0] if isinstance(x['osmid'], list) else x['osmid'], axis=1) link_attributes_df['lanes'] = link_attributes_df.apply( lambda x: x['lanes'][0] if isinstance(x['lanes'], list) else x['lanes'], axis=1) if 'maxspeed' not in link_attributes_df.columns: link_attributes_df['maxspeed'] = np.nan link_attributes_df['maxspeed'] = link_attributes_df.apply( lambda x: x['maxspeed'][0] if isinstance(x['maxspeed'], list) else x['maxspeed'], axis=1) link_df_index_list = link_attributes_df.index others_link_type_set = set() for link_index in link_df_index_list: link = MacroLink() link.original_link_id = str(link_attributes_df.loc[link_index, 'osmid']) if new_link_id_starting_from_one: link.link_id = str(g_number_of_macro_links + 1) else: link.link_id = link.original_link_id link.name = link_attributes_df.loc[link_index, 'name'] link_type_osm = link_attributes_df.loc[link_index, 'highway'] if link_type_osm not in osm_link_type_dict.keys(): link_type = 'others' if link_type_osm not in others_link_type_set: others_link_type_set.add(link_type_osm) else: link_type = osm_link_type_dict[link_type_osm] link.link_type = link_type link.link_type_code = link_type_code_dict[link_type] number_of_lanes = link_attributes_df.loc[link_index, 'lanes'] oneway = link_attributes_df.loc[link_index, 'oneway'] if number_of_lanes == number_of_lanes: link.number_of_lanes = int(number_of_lanes) if oneway else np.ceil( int(number_of_lanes) / 2) else: if use_default_value: link.number_of_lanes = default_number_of_lanes[link.link_type] max_speed = link_attributes_df.loc[link_index, 'maxspeed'] if max_speed == max_speed: link.speed_limit = float( max_speed[:-4]) if 'mph' in max_speed else float(max_speed) else: if use_default_value: link.speed_limit = default_speed_limit[link.link_type] if use_default_value: link.capacity = default_lane_cap[ link.link_type] * link.number_of_lanes original_from_node_id = link_attributes_df.loc[link_index, 'u'] original_to_node_id = link_attributes_df.loc[link_index, 'v'] if new_node_id_starting_from_one: link.from_node_id = g_original_node_id_to_new_node_id_dict[ original_from_node_id] link.to_node_id = g_original_node_id_to_new_node_id_dict[ original_to_node_id] else: link.from_node_id = original_from_node_id link.to_node_id = original_to_node_id link.length = link_attributes_df.loc[link_index, 'length'] / 1000 * 0.6214 link.geometry = link_attributes_df.loc[link_index, 'geometry'] if oneway: g_macro_link_list.append(link) g_number_of_macro_links += 1 else: link_r = copy.deepcopy(link) link.link_id = f'{link.link_id}a' link_r.link_id = f'{link_r.link_id}b' link_r.from_node_id, link_r.to_node_id = link.to_node_id, link.from_node_id link_r.geometry = LineString( list(reversed(list(link.geometry.coords)))) g_macro_link_list.append(link) g_macro_link_list.append(link_r) g_number_of_macro_links += 2 print( f' following osm link types are represented by \'others\': {others_link_type_set}' )
import matplotlib.animation as animation import random from geographiclib.geodesic import Geodesic import time geod = Geodesic.WGS84 G = ox.graph_from_bbox(1.3763, 1.3007, 103.6492, 103.7840, network_type='drive') #, simplify=True) G = ox.add_edge_speeds(G) G = ox.add_edge_travel_times(G) projected_graph = ox.project_graph(G, to_crs="EPSG:3395") Gc = ox.consolidate_intersections(projected_graph, dead_ends=True) edges = ox.graph_to_gdfs(ox.get_undirected(Gc), nodes=False) vehnumber = 10 routes = [] route = [] allAngleList = [] direction = [] all_route_roadnames = [] all_route_speeds = [] angleList = [] direzione = [] route_roadnames = [] route_speed = []
#the +- .02 is to give a little buffer room in case the path needs to take a short detour, #without it the path may not be found in the graph (or the wrong path is found) #increasing it much more than this significantly slows down loading the graph though north = max(start[0], end[0]) + .01 south = min(start[0], end[0]) - .01 east = max(start[1], end[1]) + .01 west = min(start[1], end[1]) - .01 load = int(input("load from bigBoston.graphml (1 or 0): ")) if load == 0: print("Generating graph:") t0 = time.time() G = ox.graph_from_bbox(north, south, east, west, network_type='drive') Gp = ox.project_graph(G) Gc = ox.consolidate_intersections(Gp, rebuild_graph=True, tolerance=20, dead_ends=False) t1 = time.time() print("time to generate graph: ", t1 - t0) elif load == 1: print("loading graph:") t0 = time.time() #G = ox.io.load_graphml("bigBoston.graphml") cant use this bc it calls read_graphml wrong # all this code is essentially just copying load_graphml and fixing what was wrong with load_graphml default_node_dtypes = { "elevation": float, "elevation_res": float, "lat": float, "lon": float, "osmid": int,
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) # remove degree=2 nodes G = graphs.nX_remove_filler_nodes(G)
ox.settings.useful_tags_path = [ 'bridge', 'tunnel', 'oneway', 'lanes', 'highway', 'maxspeed', 'service', 'access', 'area', 'landuse', 'width', 'est_width', 'junction', 'cycleway:right', 'cycleway:left', 'surface', 'cycleway' ] ## load graph #G = ox.graph_from_place('Philadelphia, Pennsylvania, USA', network_type='bike',simplify=False) G = ox.graph_from_point((39.94671, -75.16263), 200, simplify=True, network_type='bike') G.get_edge_data(5562127539, 109860453) G_proj = ox.project_graph(G) G_consolidate = ox.consolidate_intersections(G_proj, tolerance=10, rebuild_graph=True) ox.plot_graph(G, 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) edges = ox.graph_to_gdfs(G, nodes=False) edges.surface.apply(lambda x: [x])
def main(): # simple timer for log file start = time.time() script = os.path.basename(sys.argv[0]) task = 'Create network resources' conn = psycopg2.connect(database=db, user=db_user, password=db_pwd, host=db_host, port=db_port) curs = conn.cursor() engine = create_engine(f"postgresql://{db_user}:{db_pwd}@{db_host}/{db}") if network_not_using_buffered_region: network_study_region = study_region else: network_study_region = buffered_study_region if not (engine.has_table('edges') and engine.has_table('nodes') and engine.has_table(intersections_table)): print("\nGet networks and save as graphs.") ox.config(use_cache=True, log_console=True) if osmnx_retain_all == 'False': retain_all = False print(''' Note: "retain_all = False" ie. only main network segment is retained. Please ensure this is appropriate for your study region (ie. networks on real islands may be excluded). ''') else: retain_all = True print(''' Note: "retain_all = True" ie. all network segments will be retained. Please ensure this is appropriate for your study region (ie. networks on real islands will be included, however network artifacts resulting in isolated network segments, or network islands, may also exist. These could be problematic if sample points are snapped to erroneous, mal-connected segments. Check results.). ''') for network in ['all', 'pedestrian']: graphml = os.path.join( locale_dir, f'{network_study_region}_{network}_{osm_prefix}.graphml') if os.path.isfile(graphml): print( f'Network "{network}" for {network_study_region} has already been processed.' ) if network == 'pedestrian': G = ox.load_graphml(graphml) else: print(f'Creating and saving {network} roads network... '), subtime = datetime.now() # load buffered study region in EPSG4326 from postgis sql = f'''SELECT geom_4326 AS geom FROM {network_study_region}''' polygon = gpd.GeoDataFrame.from_postgis( sql, engine, geom_col='geom')['geom'][0] if not network_polygon_iteration: if network == 'pedestrian': G = ox.graph_from_polygon(polygon, custom_filter=pedestrian, retain_all=retain_all, network_type='walk') else: G = ox.graph_from_polygon(polygon, network_type='all', retain_all=retain_all) else: # We allow for the possibility that multiple legitimate network islands may exist in this region (e.g. Hong Kong). # These are accounted for by retrieving the network for each polygon in the buffered study region boundary, # and then taking the union of these using network compose if more than one network was retrieved. N = list() for poly in polygon: if network == 'pedestrian': try: N.append( ox.graph_from_polygon( poly, custom_filter=pedestrian, retain_all=retain_all, network_type='walk')) except: # if the polygon results in no return results from overpass, an error is thrown pass else: try: N.append( ox.graph_from_polygon( poly, network_type='all', retain_all=retain_all)) except: # skip error pass G = N[0] if len(N) > 1: for additional_network in N[1:]: G = nx.compose(G, additional_network) if type(network_connection_threshold) == int: # A minimum total distance has been set for each induced network island; so, extract the node IDs of network components exceeding this threshold distance # get all connected graph components, sorted by size cc = sorted(nx.weakly_connected_components(G), key=len, reverse=True) nodes = [] for c in cc: if len(c) >= network_connection_threshold: nodes.extend(c) nodes = set(nodes) # induce a subgraph on those nodes G = nx.MultiDiGraph(G.subgraph(nodes)) ox.save_graphml(G, filepath=graphml, gephi=False) ox.save_graph_shapefile(G, filepath=graphml.strip('.graphml')) if network == 'pedestrian': for feature in ['edges', 'nodes']: if not engine.has_table(feature): print( f"\nCopy the pedestrian network {feature} from shapefiles to Postgis..." ), command = ( ' ogr2ogr -overwrite -progress -f "PostgreSQL" ' f' PG:"host={db_host} port={db_port} dbname={db}' f' user={db_user} password={db_pwd}" ' f' {locale_dir}/{network_study_region}_{network}_{osm_prefix}/{feature}.shp ' f' -t_srs EPSG:{srid} ' ' -lco geometry_name="geom"') print(command) sp.call(command, shell=True) if not engine.has_table(intersections_table): ## Copy clean intersections to postgis print("\nPrepare and copy clean intersections to postgis... ") # Clean intersections G_proj = ox.project_graph(G) intersections = ox.consolidate_intersections( G_proj, tolerance=intersection_tolerance, rebuild_graph=False, dead_ends=False) intersections.crs = G_proj.graph['crs'] intersections_latlon = intersections.to_crs(epsg=4326) points = ', '.join([ "(ST_GeometryFromText('{}',4326))".format(x.wkt) for x in intersections_latlon ]) sql = f''' DROP TABLE IF EXISTS {intersections_table}; CREATE TABLE {intersections_table} (point_4326 geometry); INSERT INTO {intersections_table} (point_4326) VALUES {points}; ALTER TABLE {intersections_table} ADD COLUMN geom geometry; UPDATE {intersections_table} SET geom = ST_Transform(point_4326,{srid}); ALTER TABLE {intersections_table} DROP COLUMN point_4326; ''' engine.execute(sql) print(" - Done.") else: print( " - It appears that clean intersection data has already been prepared and imported for this region." ) else: print( "\nIt appears that edges, nodes and clean intersection data have already been prepared and imported for this region." ) curs.execute( '''SELECT 1 WHERE to_regclass('public.edges_target_idx') IS NOT NULL;''' ) res = curs.fetchone() if res is None: print("\nCreate network topology...") sql = ''' ALTER TABLE edges ADD COLUMN IF NOT EXISTS "source" INTEGER; ALTER TABLE edges ADD COLUMN IF NOT EXISTS "target" INTEGER; --SELECT pgr_createTopology('edges',0.0001,'geom','ogc_fid'); ''' engine.execute(sql) curs.execute("SELECT MIN(ogc_fid), MAX(ogc_fid) FROM edges;") min_id, max_id = curs.fetchone() print(f"there are {max_id - min_id + 1} edges to be processed") curs.close() interval = 10000 for x in range(min_id, max_id + 1, interval): curs = conn.cursor() curs.execute( f"select pgr_createTopology('edges', 1, 'geom', 'ogc_fid', rows_where:='ogc_fid>={x} and ogc_fid<{x+interval}');" ) conn.commit() x_max = x + interval - 1 if x_max > max_id: x_max = max_id print(f"edges {x} - {x_max} processed") sql = ''' CREATE INDEX IF NOT EXISTS edges_source_idx ON edges("source"); CREATE INDEX IF NOT EXISTS edges_target_idx ON edges("target"); ''' engine.execute(sql) else: print( " - It appears that the routable pedestrian network has already been set up for use by pgRouting." ) # ensure user is granted access to the newly created tables engine.execute(grant_query) script_running_log(script, task, start) # clean up conn.close()