def station_split(osmdb, gtfsdb, split_threshold = 50, range = 0.005): # meters (max distance to link node), degrees (intersection box size) split_idx = 1000000000 # base node/edge number. above usual OSM ids, but still leaves half of 32bit int range. n_stops = gtfsdb.count_stops() n_edges = osmdb.count_edges() #edge_index = Rtree(osmdb_filename+'-edges') edge_index = Rtree() def index_subedge(rid, pair, edge_id) : ((s_lon, s_lat), (e_lon, e_lat)) = pair box = (min(s_lon, e_lon), min(s_lat, e_lat), max(s_lon, e_lon), max(s_lat, e_lat)) # Need our own index number to remove edges as we go along. # This index could ideally be generated automatically, with collision detection. edge_index.add( rid, box, obj = (edge_id, pair) ) new_nodes = {} # for keeping track of where new nodes are added print 'indexing OSM sub-way sub-edges into rtree' progress = 0 for edge_id, way_id, from_nd, to_nd, dist, coords, tags in osmdb.edges() : new_nodes [edge_id] = [] # an empty placeholder list to be filled in when new nodes are created along this edge for subedge_number, pair in enumerate(cons(coords)) : # make id the subedge number along the parent edge index_subedge(subedge_number, pair, edge_id) # take first element because db response is a tuple if progress % 1000 == 0 : sys.stdout.write('\rEdge %d/%d' % (progress, n_edges)) sys.stdout.flush() progress += 1 print def nearest_point_on_subedge((subedge_rid, (edge_id, pair), subedge_bbox), stop_lat, stop_lon) : # print "finding nearest point on edge %s (rtree id %d)" % (edge_id, edge_rid) ((s_lon, s_lat), (e_lon, e_lat)) = pair # print (s_lat, s_lon, e_lat, e_lon, stop_lat, stop_lon) stop = lg.GPoint(stop_lon, stop_lat) ls = lg.LineString([(s_lon, s_lat), (e_lon, e_lat)], geographic=True) dist = ls.distance_pt(stop) pt = ls.closest_pt(stop) loc = ls.locate_point(pt) return subedge_rid, edge_id, pair, subedge_bbox, dist, pt, loc
# New nodes have been created as necessary. Delete old edges and add new ones between the new nodes. print 'Removing old edges and adding new ones...' progress=0 for edge_id, node_list in new_nodes.items() : progress += 1 if progress % 100 == 0 : sys.stdout.write('\rEdge %d/%d' % (progress, n_edges)) sys.stdout.flush() if len(node_list) == 0 : continue # get information about the edge to be replaced edge_id, way_id, from_nd, to_nd, edge_length, coords, tags = osmdb.edge(edge_id) # find distance and length for each sub-edge subedges = [] c_dist = 0 for (lon1, lat1), (lon2, lat2) in cons(coords) : dist = geoid_dist(lat1, lon1, lat2, lon2) subedges.append((c_dist, dist)) c_dist += dist print '\nedge: ', edge_id print 'subedges: ', subedges print 'new node list: ', node_list # sort new nodes by subedge index and location within subedge node_list.sort( key = lambda x: float(x[1]) + x[2] ) c = osmdb.cursor() last_node_id = from_nd dist = 0 subedge_idx = 0 while len(node_list) > 0 : node_id, node_subedge, node_loc = node_list.pop(0) # take from beginning not end of list - otherwise sort is reversed.