in libs/apls/wkt_to_G.py [0: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)