tomalrussell / snkit

spatial networks toolkit (python)
MIT License
31 stars 10 forks source link

Link node to nearest edge (which it does not already touch) #19

Open tomalrussell opened 5 years ago

tomalrussell commented 5 years ago

For example, given a set of edges, add endpoints, then connect those endpoints to other edges (maybe given some condition).

Notes:

ElcoK commented 5 years ago

Suggested function to add (or at least a first version for a new one):

def nearest_not_intersecting(node, gdf, condition,threshold=0.01):
    """Find the element of a GeoDataFrame nearest a shapely geometry
    """
    geom = node.geometry
    n = 10
    step = 10
    while True:
        matches_idx = gdf.sindex.nearest(geom.bounds, n)
        candidate_idxs = []
        k = 0
        for match_idx in matches_idx:
            edge = gdf.iloc[match_idx]
            distance = geom.distance(edge.geometry) 
            if (edge.infra_type == node.infra_type) & (distance == 0):
                k += 1
            if not condition(node, edge):
                continue
            if 0 < distance <= threshold:
                candidate_idxs.append(match_idx)

        if k > 2:
            break

        if candidate_idxs:            
            nearest_geom = min(
                [gdf.iloc[match_idx] for match_idx in candidate_idxs],
                key=lambda match: geom.distance(match.geometry)
            )
            return nearest_geom
        n = n + step
        if n > 10:
            break