def wkt_to_G()

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)