def _points(self, vertex_label, starttime, cutoff, speed): starttime = starttime or time.time() #=== find shortest path tree === print "Finding shortest path tree" t0 = time.time() wo = WalkOptions() wo.walking_speed = speed spt = self.graph.shortest_path_tree( vertex_label, None, State(1,starttime), wo, maxtime=starttime+int(cutoff*1.25) ) wo.destroy() t1 = time.time() print "took %s s"%(t1-t0) #=== cobble together ETA surface === print "Creating ETA surface from OSM points..." points = [] t0 = time.time() for vertex in spt.vertices: if "osm" in vertex.label: x, y = self.node_positions[vertex.label[3:]] points.append( (x, y, vertex.payload.time-starttime) ) t1 = time.time() print "Took %s s"%(t1-t0) spt.destroy() return points
def path_retro(self, origin, dest, currtime=None, time_offset=None, transfer_penalty=0, walking_speed=1.0): if currtime is None: currtime = int(time.time()) if time_offset is not None: currtime += time_offset wo = WalkOptions() wo.transfer_penalty = transfer_penalty wo.walking_speed = walking_speed spt = self.graph.shortest_path_tree_retro(origin, dest, State(1, currtime), wo) wo.destroy() vertices, edges = spt.path_retro(origin) ret = list( postprocess_path(vertices, edges, self.vertex_events, self.edge_events)) spt.destroy() return json.dumps(ret, indent=2, cls=SelfEncoderHelper)
def vertex(self, label, currtime=None, hill_reluctance=1.5, walking_speed=0.85): currtime = currtime or int(time.time()) ret = [] ret.append( "<h1>%s</h1>"%label ) wo = WalkOptions() ret.append( "<h3>walk options</h3>" ) ret.append( "<li>transfer_penalty: %s</li>"%wo.transfer_penalty ) ret.append( "<li>turn_penalty: %s</li>"%wo.turn_penalty ) ret.append( "<li>walking_speed: %s</li>"%wo.walking_speed ) ret.append( "<li>walking_reluctance: %s</li>"%wo.walking_reluctance ) ret.append( "<li>uphill_slowness: %s</li>"%wo.uphill_slowness ) ret.append( "<li>downhill_fastness: %s</li>"%wo.downhill_fastness ) ret.append( "<li>hill_reluctance: %s</li>"%wo.hill_reluctance ) ret.append( "<li>max_walk: %s</li>"%wo.max_walk ) ret.append( "<li>walking_overage: %s</li>"%wo.walking_overage ) ret.append( "<h3>incoming from:</h3>" ) for i, (vertex1, vertex2, edgetype) in enumerate( self.graphdb.all_incoming( label ) ): s1 = State(1,int(currtime)) wo = WalkOptions() wo.hill_reluctance=hill_reluctance wo.walking_speed=walking_speed s0 = edgetype.walk_back( s1, wo ) if s0: toterm = "<a href=\"/vertex?label="%s"&currtime=%d\">%s@%d</a>"%(vertex1, s0.time, vertex1, s1.time) else: toterm = "<a href=\"/vertex?label="%s"\">%s</a>"%(vertex1, vertex1) ret.append( "%s<br><pre> via %s (<a href=\"/incoming?label="%s"&edgenum=%d\">details</a>)</pre>"%(toterm, cgi.escape(repr(edgetype)), vertex2, i) ) if s0: ret.append( "<pre> %s</pre>"%cgi.escape(str(s0)) ) ret.append( "<h3>outgoing to:</h3>" ) for i, (vertex1, vertex2, edgetype) in enumerate( self.graphdb.all_outgoing( label ) ): s0 = State(1,int(currtime)) wo = WalkOptions() wo.hill_reluctance=hill_reluctance wo.walking_speed=walking_speed s1 = edgetype.walk( s0, wo ) if s1: toterm = "<a href=\"/vertex?label="%s"&currtime=%d\">%s@%d</a>"%(vertex2, s1.time, vertex2, s1.time) else: toterm = "<a href=\"/vertex?label="%s"\">%s</a>"%(vertex2, vertex2) ret.append( "%s<br><pre> via %s (<a href=\"/outgoing?label="%s"&edgenum=%d\">details</a>)</pre>"%(toterm, cgi.escape(repr(edgetype)), vertex1, i) ) if s1: ret.append( "<pre> %s</pre>"%cgi.escape(str(s1)) ) wo.destroy() return "".join(ret)
def path(self, lat1, lng1, lat2, lng2, transfer_penalty=0, walking_speed=1.0, hill_reluctance=20, narrative=True, jsoncallback=None): t0 = time.time() origin = "osm-%s"%self.osmdb.nearest_node( lat1, lng1 )[0] dest = "osm-%s"%self.osmdb.nearest_node( lat2, lng2 )[0] endpoint_find_time = time.time()-t0 print origin, dest t0 = time.time() wo = WalkOptions() #wo.transfer_penalty=transfer_penalty #wo.walking_speed=walking_speed wo.walking_speed=4 wo.walking_overage = 0 wo.hill_reluctance = 20 wo.turn_penalty = 15 edgepayloads = self.ch.shortest_path( origin, dest, State(1,0), wo ) wo.destroy() route_find_time = time.time()-t0 t0 = time.time() names = [] geoms = [] profile = Profile() total_dist = 0 total_elev = 0 if narrative: names, total_dist = get_full_route_narrative( self.osmdb, edgepayloads ) for edgepayload in edgepayloads: geom, profile_seg = self.shortcut_cache.get( edgepayload.external_id ) #geom = get_ep_geom( self.osmdb, edgepayload ) #profile_seg = get_ep_profile( self.profiledb, edgepayload ) geoms.extend( geom ) profile.add( profile_seg ) route_desc_time = time.time()-t0 ret = json.dumps( (names, encode_pairs( [(lat, lon) for lon, lat in geoms] ), profile.concat(300), { 'route_find_time':route_find_time, 'route_desc_time':route_desc_time, 'endpoint_find_time':endpoint_find_time,}, { 'total_dist':total_dist, 'total_elev':total_elev}) ) if jsoncallback: return "%s(%s)"%(jsoncallback,ret) else: return ret
def _walk_edges_general(self, forward_dir, label, time): vertex = self.gg.get_vertex( label ) init_state = self._parse_init_state(self.gg.numagencies, time) dest_states = [] for edge in vertex.outgoing: if forward_dir: if hasattr( edge.payload, 'collapse' ): collapsed = edge.payload.collapse( init_state ) else: collapsed = edge.payload if collapsed: wo = WalkOptions() dest_states.append( (edge, collapsed, collapsed.walk( init_state,wo )) ) wo.destroy() else: if hasattr( edge.payload, 'collapse_back' ): collapsed = edge.payload.collapse_back( init_state ) else: collapsed = edge.payload if collapsed: wo = WalkOptions() dest_states.append( (edge, collapsed, collapsed.walk_back( init_state,wo )) ) wo.destroy() def sort_states(x,y): if x[2] is None: return 1 if y[2] is None: return -1 else: return cmp(x[2].weight, y[2].weight) dest_states.sort(cmp=sort_states) #sort by weight of final state #==================== ret = ["<?xml version='1.0'?>"] ret.append("<vertex>") ret.append(init_state.to_xml()) ret.append("<outgoing_edges>") for edge, collapsed, sprime in dest_states: ret.append("<edge>") ret.append("<destination label='%s'>" % edge.to_v.label) if sprime: ret.append(sprime.to_xml()) else: ret.append("<state/>") ret.append("</destination>") if collapsed: ret.append("<payload>%s</payload>" % collapsed.to_xml()) else: ret.append("<payload/>") ret.append("</edge>") ret.append("</outgoing_edges>") ret.append("</vertex>") return "".join(ret)
def path(self, origin, dest, currtime=None, time_offset=None, transfer_penalty=0, walking_speed=1.0, hill_reluctance=1.5, turn_penalty=None, walking_reluctance=None, max_walk=None, jsoncallback=None): performance = {} if currtime is None: currtime = int(time.time()) if time_offset is not None: currtime += time_offset # time path query t0 = time.time() wo = WalkOptions() wo.transfer_penalty = transfer_penalty wo.walking_speed = walking_speed wo.hill_reluctance = hill_reluctance if turn_penalty is not None: wo.turn_penalty = turn_penalty if walking_reluctance is not None: wo.walking_reluctance = walking_reluctance if max_walk is not None: wo.max_walk = max_walk spt = self.graph.shortest_path_tree(origin, dest, State(1, currtime), wo) vertices, edges = spt.path(dest) performance['path_query_time'] = time.time() - t0 t0 = time.time() narrative = list( postprocess_path(vertices, edges, self.vertex_events, self.edge_events)) performance['narrative_postprocess_time'] = time.time() - t0 t0 = time.time() wo.destroy() spt.destroy() performance['cleanup_time'] = time.time() - t0 ret = {'narrative': narrative, 'performance': performance} if jsoncallback is None: return json.dumps(ret, indent=2, cls=SelfEncoderHelper) else: return "%s(%s)" % ( jsoncallback, json.dumps(ret, indent=2, cls=SelfEncoderHelper))
def path(self, origin, dest, currtime=None, time_offset=None, transfer_penalty=0, walking_speed=1.0, hill_reluctance=1.5, turn_penalty=None, walking_reluctance=None, max_walk=None, jsoncallback=None): performance = {} if currtime is None: currtime = int(time.time()) if time_offset is not None: currtime += time_offset # time path query t0 = time.time() wo = WalkOptions() wo.transfer_penalty=transfer_penalty wo.walking_speed=walking_speed wo.hill_reluctance=hill_reluctance if turn_penalty is not None: wo.turn_penalty = turn_penalty if walking_reluctance is not None: wo.walking_reluctance = walking_reluctance if max_walk is not None: wo.max_walk = max_walk spt = self.graph.shortest_path_tree( origin, dest, State(1,currtime), wo ) vertices, edges = spt.path( dest ) performance['path_query_time'] = time.time()-t0 t0 = time.time() narrative = list(postprocess_path(vertices, edges, self.vertex_events, self.edge_events)) performance['narrative_postprocess_time'] = time.time()-t0 t0 = time.time() wo.destroy() spt.destroy() performance['cleanup_time'] = time.time()-t0 ret = {'narrative':narrative, 'performance':performance} if jsoncallback is None: return json.dumps(ret, indent=2, cls=SelfEncoderHelper) else: return "%s(%s)"%(jsoncallback,json.dumps(ret, indent=2, cls=SelfEncoderHelper))
def path_raw_retro(self, origin, dest, currtime): wo = WalkOptions() spt = self.graph.shortest_path_tree_retro( origin, dest, State(1,currtime), wo ) wo.destroy() vertices, edges = spt.path_retro( origin ) ret = postprocess_path_raw(vertices, edges) spt.destroy() return ret
def path_raw_retro(self, origin, dest, currtime): wo = WalkOptions() spt = self.graph.shortest_path_tree_retro( origin, dest, State(1,currtime), wo ) wo.destroy() vertices, edges = spt.path_retro( origin ) ret = postprocess_path_raw(vertices, edges) spt.destroy() return ret
def path_raw_retro(self, origin, dest, currtime): wo = WalkOptions() spt = self.graph.shortest_path_tree_retro( origin, dest, State(1,currtime), wo ) wo.destroy() vertices, edges = spt.path_retro( origin ) ret = "\n".join([str(x) for x in vertices]) + "\n\n" + "\n".join([str(x) for x in edges]) spt.destroy() return ret
def path_raw(self, origin, dest, currtime=None): if currtime is None: currtime = int(time.time()) wo = WalkOptions() spt = self.graph.shortest_path_tree( origin, dest, State(1,currtime), wo ) wo.destroy() vertices, edges = spt.path( dest ) ret = postprocess_path_raw(vertices, edges) spt.destroy() return ret
def path_raw(self, origin, dest, currtime=None): if currtime is None: currtime = int(time.time()) wo = WalkOptions() spt = self.graph.shortest_path_tree( origin, dest, State(1,currtime), wo ) wo.destroy() vertices, edges = spt.path( dest ) ret = postprocess_path_raw(vertices, edges) spt.destroy() return ret
def path_retro(self, origin, dest, currtime, transfer_penalty=0, walking_speed=1.0): wo = WalkOptions() wo.transfer_penalty = transfer_penalty wo.walking_speed = walking_speed spt = self.graph.shortest_path_tree_retro( origin, dest, State(1,currtime), wo ) wo.destroy() vertices, edges = spt.path_retro( origin ) ret = [] for i in range(len(edges)): edgetype = edges[i].payload.__class__ if edgetype in self.event_dispatch: ret.append( self.event_dispatch[ edges[i].payload.__class__ ]( vertices[i], edges[i], vertices[i+1] ) ) spt.destroy() return json.dumps(ret)
def vertex(self, label, currtime=None): currtime = currtime or int(time.time()) ret = [] ret.append( "<h1>%s</h1>"%label ) ret.append( "<h3>incoming from:</h3>" ) for i, (vertex1, vertex2, edgetype) in enumerate( self.graphdb.all_incoming( label ) ): s1 = State(1,int(currtime)) wo = WalkOptions() s0 = edgetype.walk_back( s1, wo ) wo.destroy() if s0: toterm = "<a href=\"/vertex?label="%s"&currtime=%d\">%s@%d</a>"%(vertex1, s0.time, vertex1, s1.time) else: toterm = "<a href=\"/vertex?label="%s"\">%s</a>"%(vertex1, vertex1) ret.append( "%s<br><pre> via %s (<a href=\"/incoming?label="%s"&edgenum=%d\">details</a>)</pre>"%(toterm, cgi.escape(repr(edgetype)), vertex2, i) ) if s0: ret.append( "<pre> %s</pre>"%cgi.escape(str(s0)) ) ret.append( "<h3>outgoing to:</h3>" ) for i, (vertex1, vertex2, edgetype) in enumerate( self.graphdb.all_outgoing( label ) ): s0 = State(1,int(currtime)) wo = WalkOptions() s1 = edgetype.walk( s0, wo ) wo.destroy() if s1: toterm = "<a href=\"/vertex?label="%s"&currtime=%d\">%s@%d</a>"%(vertex2, s1.time, vertex2, s1.time) else: toterm = "<a href=\"/vertex?label="%s"\">%s</a>"%(vertex2, vertex2) ret.append( "%s<br><pre> via %s (<a href=\"/outgoing?label="%s"&edgenum=%d\">details</a>)</pre>"%(toterm, cgi.escape(repr(edgetype)), vertex1, i) ) if s1: ret.append( "<pre> %s</pre>"%cgi.escape(str(s1)) ) return "".join(ret)
def path_retro(self, origin, dest, currtime=None, time_offset=None, transfer_penalty=0, walking_speed=1.0): if currtime is None: currtime = int(time.time()) if time_offset is not None: currtime += time_offset wo = WalkOptions() wo.transfer_penalty = transfer_penalty wo.walking_speed = walking_speed spt = self.graph.shortest_path_tree_retro( origin, dest, State(1,currtime), wo ) wo.destroy() vertices, edges = spt.path_retro( origin ) ret = list(postprocess_path(vertices, edges, self.vertex_events, self.edge_events)) spt.destroy() return json.dumps(ret, indent=2, cls=SelfEncoderHelper)
class Proccessing(): def get_gs_vertex(self, point_id): self.cursor.execute('SELECT vertex_label FROM cal_corres_vertices WHERE point_id=%s', ( point_id, )) return self.cursor.fetchone()[0] def get_point(self, vertex_label): self.cursor.execute('SELECT point_id FROM cal_corres_vertices WHERE vertex_label=%s', ( vertex_label, )) return [x[0] for x in self.cursor][0] def prepare_times(self, start_time, end_time): times = [] start = time.mktime(start_time.timetuple()) end = time.mktime(end_time.timetuple()) t = start while t <= end: times.append(t) t += self.time_step return times def get_route_dict(self): self.cursor.execute('SELECT origin, destination, time FROM cal_routes WHERE NOT done LIMIT 1') row = self.cursor.fetchone() if row: origin, destination, time = row else: # there are no routes to Compute return None self.cursor.execute('SELECT start_time, end_time, is_arrival_time FROM cal_times WHERE id=%s', ( time, )) start_time, end_time, is_arrival = self.cursor.fetchone() if is_arrival: return self.get_retro_dict(destination, time, start_time, end_time) else: return self.get_dict(origin, time, start_time, end_time) def get_retro_dict(self, destination, time, start_time, end_time): self.cursor.execute('''SELECT id, origin FROM cal_routes WHERE destination=%s AND time=%s''', ( destination, time )) origins = list(self.cursor.fetchall()) self.cursor.execute('UPDATE cal_routes SET done=%s WHERE destination=%s AND time=%s', ( True, destination, time )) self.conn.commit() return { 'destination':self.get_gs_vertex(destination), 'times':self.prepare_times(start_time, end_time), 'arrival':True, 'origins':[ ( self.get_gs_vertex(orig[1]), orig[0] ) for orig in origins ] } def get_dict(self, origin, time, start_time, end_time): self.cursor.execute('''SELECT id, destination FROM cal_routes WHERE origin=%s AND time=%s''', ( origin, time )) destinations = list(self.cursor.fetchall()) self.cursor.execute('UPDATE cal_routes SET done=%s WHERE origin=%s AND time=%s', ( True, origin, time )) self.conn.commit() return { 'origin':self.get_gs_vertex(origin), 'times':self.prepare_times(start_time, end_time), 'arrival':False, 'destinations':[ ( self.get_gs_vertex(dest[1]), dest[0] ) for dest in destinations ] } def process_paths(self, routes): for t in routes['times']: s = State(1, t) # build the shortest path tree at time 't' try: if len(routes['destinations']) > 1: spt = self.graph.shortest_path_tree(routes['origin'], None, s, self.walk_ops) else: spt = self.graph.shortest_path_tree(routes['origin'],routes['destinations'][0][0], s, self.walk_ops) # faster but only ONE destination except: pass # extract the actual routes and write them into the database for dest in routes['destinations']: try: vertices, edges = spt.path(dest[0]) if not vertices: raise Exception() except: self.write_error_trip(t, dest[1]) else: self.write_trip(vertices, dest[1]) # cleanup try: spt.destroy() except: pass def process_retro_paths(self, routes): for t in routes['times']: s = State(1, t) # build the shortest path tree at time 't' try: if len(routes['origins']) > 1: spt = self.graph.shortest_path_tree_retro(None, routes['destination'], s,self.walk_ops) else: spt = self.graph.shortest_path_tree_retro(routes['origins'][0][0], routes['destination'], s, self.walk_ops) # faster but only ONE destination except: pass # extract the actual routes and write them into the database for orig in routes['origins']: try: vertices, edges = spt.path_retro(orig[0]) if not vertices: raise Exception() except: self.write_error_trip(t, orig[1]) else: self.write_retro_trip(vertices, orig[1]) # cleanup try: spt.destroy() except: pass def run(self): ''' method for processing (calculating shortest paths) all routes stored inside the databases associated with this object. [only routes with the processed flag not set will be processed] ''' routes = self.get_route_dict() while ( routes ): if routes['arrival']: self.process_retro_paths(routes) else: self.process_paths(routes) routes = self.get_route_dict() def write_retro_trip(self, vertices, route_id): ''' in retro_paths the walking distance is counted in the wrong direction. this method corrects this. ''' # now done in write_results self.write_trip(vertices, route_id) def write_trip(self, vertices, route_id): current_trip_id = str(self.trip_id) self.trip_id += 1 start_time = datetime.datetime.fromtimestamp(vertices[0].state.time) end_time = datetime.datetime.fromtimestamp(vertices[-1].state.time) self.cursor.execute('INSERT INTO cal_paths VALUES (%s,%s,%s,%s,%s)', ( self.trip_prefix + current_trip_id, route_id, start_time, end_time, (vertices[-1].state.time - vertices[0].state.time ) )) for c, v in enumerate(vertices): time = datetime.datetime.fromtimestamp(v.state.time) self.cursor.execute('INSERT INTO cal_paths_details VALUES (%s,%s,%s,%s,%s,%s,%s,%s)', ( self.trip_prefix + current_trip_id, c, v.label, time, v.state.weight, v.state.dist_walked, v.state.num_transfers, v.state.trip_id )) if not self.trips_calculated % 1000: self.conn.commit() self.logfile.write('%s routes calculated by %s, last route: %s \n' %(self.trips_calculated, self.trip_prefix, route_id)) self.logfile.flush() self.trips_calculated += 1 ''' this method will write a very long trip into the database. ''' def write_error_trip(self, start_time, route_id): current_trip_id = str(self.trip_id) self.trip_id += 1 start_date_time = datetime.datetime.fromtimestamp(start_time) end_time = datetime.datetime(2030,12,31) self.cursor.execute('INSERT INTO cal_paths VALUES (%s,%s,%s,%s,%s)', (self.trip_prefix + current_trip_id, route_id, start_date_time, end_time, (time.mktime(end_time.timetuple()) - start_time ) )) def __init__(self, graph, db_connection_string, time_step=240, walking_speed=1.2, max_walk=1080, walking_reluctance=2, trip_prefix='', logfile = None): self.trip_prefix = trip_prefix self.time_step = time_step self.walk_ops = WalkOptions() self.walk_ops.walking_speed = walking_speed self.walk_ops.max_walk = max_walk self.walk_ops.walking_reluctance = walking_reluctance self.graph = graph self.conn = psycopg2.connect(db_connection_string) self.cursor = self.conn.cursor() self.trip_id = 0 self.trips_calculated = 0 self.logfile = logfile self.run() def __del__(self): self.walk_ops.destroy() self.cursor.close() self.conn.commit() self.graph.destroy()
def vertex(self, label, currtime=None, hill_reluctance=1.5, walking_speed=0.85): currtime = currtime or int(time.time()) ret = [] ret.append("<h1>%s</h1>" % label) wo = WalkOptions() ret.append("<h3>walk options</h3>") ret.append("<li>transfer_penalty: %s</li>" % wo.transfer_penalty) ret.append("<li>turn_penalty: %s</li>" % wo.turn_penalty) ret.append("<li>walking_speed: %s</li>" % wo.walking_speed) ret.append("<li>walking_reluctance: %s</li>" % wo.walking_reluctance) ret.append("<li>uphill_slowness: %s</li>" % wo.uphill_slowness) ret.append("<li>downhill_fastness: %s</li>" % wo.downhill_fastness) ret.append("<li>hill_reluctance: %s</li>" % wo.hill_reluctance) ret.append("<li>max_walk: %s</li>" % wo.max_walk) ret.append("<li>walking_overage: %s</li>" % wo.walking_overage) ret.append("<h3>incoming from:</h3>") for i, (vertex1, vertex2, edgetype) in enumerate(self.graphdb.all_incoming(label)): s1 = State(1, int(currtime)) wo = WalkOptions() wo.hill_reluctance = hill_reluctance wo.walking_speed = walking_speed s0 = edgetype.walk_back(s1, wo) if s0: toterm = "<a href=\"/vertex?label="%s"&currtime=%d\">%s@%d</a>" % ( vertex1, s0.time, vertex1, s1.time) else: toterm = "<a href=\"/vertex?label="%s"\">%s</a>" % ( vertex1, vertex1) ret.append( "%s<br><pre> via %s (<a href=\"/incoming?label="%s"&edgenum=%d\">details</a>)</pre>" % (toterm, cgi.escape(repr(edgetype)), vertex2, i)) if s0: ret.append("<pre> %s</pre>" % cgi.escape(str(s0))) ret.append("<h3>outgoing to:</h3>") for i, (vertex1, vertex2, edgetype) in enumerate(self.graphdb.all_outgoing(label)): s0 = State(1, int(currtime)) wo = WalkOptions() wo.hill_reluctance = hill_reluctance wo.walking_speed = walking_speed s1 = edgetype.walk(s0, wo) if s1: toterm = "<a href=\"/vertex?label="%s"&currtime=%d\">%s@%d</a>" % ( vertex2, s1.time, vertex2, s1.time) else: toterm = "<a href=\"/vertex?label="%s"\">%s</a>" % ( vertex2, vertex2) ret.append( "%s<br><pre> via %s (<a href=\"/outgoing?label="%s"&edgenum=%d\">details</a>)</pre>" % (toterm, cgi.escape(repr(edgetype)), vertex1, i)) if s1: ret.append("<pre> %s</pre>" % cgi.escape(str(s1))) wo.destroy() return "".join(ret)
def path_xml(self, origlon, origlat, destlon, destlat, dep_time=0, arr_time=0, max_results=1, timezone="", transfer_penalty=60, walking_speed=1.0, walking_reluctance=1.0, max_walk=10000, walking_overage=0.1, seqno=0, street_mode="walk", transit_mode="Both", less_walking="False", udid="", version="2.0", two_way_routing="True"): if (two_way_routing == "False"): self.two_way_routing = False # set hard bounds on max_results [0,25] if (max_results < 0): max_results = 0 elif (max_results > 25): max_results = 25 sys.stderr.write("[xml_path_entry_point," + str(time.time()) + "] \"origlon=" + str(origlon) + "&origlat=" + str(origlat) + "&destlon=" + str(destlon) + "&destlat=" + str(destlat) + "&dep_time=" + str(dep_time) + "&arr_time=" + str(arr_time) + "&timezone=" + str(timezone) + "&transfer_penalty=" + str(transfer_penalty) + "&walking_speed=" + str(walking_speed) + "&walking_reluctance=" + str(walking_reluctance) + "&max_walk=" + str(max_walk) + "&walking_overage=" + str(walking_overage) + "&seqno=" + str(seqno) + "&street_mode=\"" + str(street_mode) + "\"&less_walking=\"" + str(less_walking) + "\"&udid=\"" + str(udid) + "\"&version=" + str(version) + "\"\n") if (origlon <= ChicagoMap.bounding_lon_left or origlon >= ChicagoMap.bounding_lon_right or origlat <= ChicagoMap.bounding_lat_bottom or origlat >= ChicagoMap.bounding_lat_top or destlon <= ChicagoMap.bounding_lon_left or destlon >= ChicagoMap.bounding_lon_right or destlat <= ChicagoMap.bounding_lat_bottom or destlat >= ChicagoMap.bounding_lat_top): sys.stderr.write("[exit_outside_bounding_box," + str(time.time()) + "]\n") raise RoutingException #return '<?xml version="1.0"?><routes></routes>' # initialize spt to 'None' object spt = None # initialize walk options object wo = WalkOptions() # create database connections pgosmdb_conn = self.pgosmdb.create_pgosmdb_connection() pggtfsdb_conn = self.pggtfsdb.create_pggtfsdb_connection() try: # if the departure time is not specified, set it if (dep_time == 0): dep_time = int(time.time()) # if the timezone is not specified, default to "America/Chicago" if (timezone == ""): timezone = "America/Chicago" # get origin and destination nodes from osm map sys.stderr.write("[get_osm_vertex_from_coords," + str(time.time()) + "]\n") orig_osm, orig_osm_dist = self.pgosmdb.get_osm_vertex_from_coords(pgosmdb_conn, origlon, origlat) dest_osm, dest_osm_dist = self.pgosmdb.get_osm_vertex_from_coords(pgosmdb_conn, destlon, destlat) #print "\nOrigin OSM: " + str(orig_osm) + " (" + str(orig_osm_dist) + ")" #print "Destination OSM: " + str(dest_osm) + " (" + str(dest_osm_dist) + ")\n" # get origin and destination nodes from gtfs database sys.stderr.write("[get_station_vertex_from_coords," + str(time.time()) + "]\n") orig_sta, orig_sta_dist = self.pggtfsdb.get_station_vertex_from_coords(pggtfsdb_conn, origlon, origlat) dest_sta, dest_sta_dist = self.pggtfsdb.get_station_vertex_from_coords(pggtfsdb_conn, destlon, destlat) #print "Origin STA: " + str(orig_sta) + " (" + str(orig_sta_dist) + ")" #print "Destination STA: " + str(dest_sta) + " (" + str(dest_sta_dist) + ")\n" # get coordinates for origin node if (orig_osm_dist < orig_sta_dist): origin = orig_osm sys.stderr.write("[get_coords_for_osm_vertex," + str(time.time()) + "]\n") orig_node_lat, orig_node_lon = self.pgosmdb.get_coords_for_osm_vertex(pgosmdb_conn, origin) else: origin = orig_sta sys.stderr.write("[get_coords_for_station_vertex," + str(time.time()) + "]\n") orig_node_lat, orig_node_lon = self.pggtfsdb.get_coords_for_station_vertex(pggtfsdb_conn, origin) # get coordinates for destination node if (dest_osm_dist < dest_sta_dist): dest = dest_osm sys.stderr.write("[get_coords_for_osm_vertex," + str(time.time()) + "]\n") dest_node_lat, dest_node_lon = self.pgosmdb.get_coords_for_osm_vertex(pgosmdb_conn, dest) else: dest = dest_sta sys.stderr.write("[get_coords_for_station_vertex," + str(time.time()) + "]\n") dest_node_lat, dest_node_lon = self.pggtfsdb.get_coords_for_station_vertex(pggtfsdb_conn, dest) #print "Origin: " + str(origin) #print "Destination: " + str(dest) + "\n" #print "Origin coords: " + str(orig_node_lat) + ", " + str(orig_node_lon) #print "Destination coords: " + str(dest_node_lat) + ", " + str(dest_node_lon) # determine distance from actual origin/destination to osm nodes orig_distance = vincenty(float(origlat), float(origlon), orig_node_lat, orig_node_lon) dest_distance = vincenty(dest_node_lat, dest_node_lon, float(destlat), float(destlon)) #print "Origin distance: " + str(orig_distance) #print "Destination distance: " + str(dest_distance) # calculate time to origin and destination nodes (seconds) time_to_orig = int(round(float( float(orig_distance) / float(walking_speed) ))) time_to_dest = int(round(float( float(dest_distance) / float(walking_speed) ))) #print "Origin time: " + str(time_to_orig) #print "Destination time: " + str(time_to_dest) # adjust departure time by time needed to reach origin node dep_time = (dep_time + time_to_orig) # adjust arrival time by time needed to reach destination node if (arr_time != 0): arr_time = (arr_time - time_to_dest) #print "Adjusted departure time: " + str(dep_time) # set walk options wo.transfer_penalty=transfer_penalty wo.walking_speed=walking_speed wo.walking_reluctance=walking_reluctance wo.max_walk=max_walk wo.walking_overage=walking_overage # check for wheelchair street_mode if (street_mode == "wheelchair"): wo.with_wheelchair = int(True) wo.transfer_penalty = 180 else: wo.with_wheelchair = int(False) # check for bike street_mode if (street_mode == "bike"): wo.transfer_penalty = 120 # check for transit_mode if (transit_mode == "Both"): wo.transit_types = int(14) elif (transit_mode == "Bus"): wo.transit_types = int(8) elif (transit_mode == "Rail"): wo.transit_types = int(6) elif (transit_mode == "None"): wo.transit_types = int(0) # check for less_walking flag if (less_walking == "True"): wo.walking_reluctance *= 10.0 # create RouteInfo object route_info = RouteInfo() route_info.origlat = origlat route_info.origlon = origlon route_info.dep_time_diff = time_to_orig route_info.destlat = destlat route_info.destlon = destlon route_info.arr_time_diff = time_to_dest route_info.street_mode = street_mode yield "--multipart-path_xml-boundary1234\n"; # loop to create multiple responses for q in range(max_results): if (spt is not None): spt.destroy_no_hash() route_info.first_edge = True route_info.last_edge = False # initialize return string ret_string = 'Content-Type: text/xml\n\n<?xml version="1.0"?><routes>' if (arr_time == 0): (spt, edges, vertices) = self.shortest_path(origin,dest,dep_time,wo) else: (spt, edges, vertices) = self.shortest_path_retro(origin,dest,arr_time,wo) # if there are no edges or vertices (i.e., there is no path found) if ((edges is None) or (vertices is None)): raise RoutingException # create WalkPath object walk_path = WalkPath() walk_path.lastlat = origlat walk_path.lastlon = origlon walk_path.timezone = timezone # string to store returned route curr_route = "" route_info.actual_dep_time = vertices[0].payload.time - time_to_orig route_info.actual_arr_time = vertices[-1].payload.time + time_to_dest # iterate through all edges in the route sys.stderr.write("[edges_loop," + str(time.time()) + "]\n") # determine the number of edges edges_len = len(edges) for i in range(edges_len): if (i == (edges_len-1)): route_info.last_edge = True elif (i == (edges_len-2) and edges[i+1].payload.__class__ == graphserver.core.Link): route_info.last_edge = True elif (i == (edges_len-3) and edges[i+1].payload.__class__ == graphserver.core.Link and edges[i+2].payload.__class__ == graphserver.core.Link): route_info.last_edge = True edgetype = edges[i].payload.__class__ if edgetype in self.event_dispatch: (new_event, walk_path, route_info) = self.event_dispatch[ edges[i].payload.__class__ ]( vertices[i], edges[i], vertices[i+1], walk_path, route_info, pgosmdb_conn, pggtfsdb_conn) curr_route += new_event ret_string += '<route dep_time="' + str(route_info.actual_dep_time) + '" req_dep_time="' + str(dep_time - time_to_orig) + '" arr_time="' + str(route_info.actual_arr_time) + '" req_arr_time="' + str(arr_time) + '" origlat="' + str(origlat) + '" origlon="' + str(origlon) + '" destlat="' + str(destlat) + '" destlon="' + str(destlon) + '" timezone="' + timezone + '" total_time="' + str(route_info.actual_arr_time - route_info.actual_dep_time) + '" total_walk_distance="' + str(int(round(walk_path.total_distance)) + int(round(orig_distance)) + int(round(dest_distance))) + '" walking_speed="' + str(walking_speed) + '" seqno="' + str(seqno) + '" version="' + str(version) + '">' + curr_route + '</route>' # close return string if q == max_results: ret_string += '</routes>\n\n--multipart-path_xml-boundary1234--\n\n' else: ret_string += '</routes>\n\n--multipart-path_xml-boundary1234\n' sys.stderr.write("[xml_path_exit_point," + str(time.time()) + "]\n") # return routes xml yield xstr(str(ret_string)) if arr_time == 0: dep_time = route_info.actual_dep_time + time_to_orig + 60 else: arr_time = route_info.actual_arr_time - time_to_dest - 60 except RoutingException: if (spt is not None): spt.destroy_no_hash() yield '\n\n--multipart-path_xml-boundary1234\nContent-Type: text/xml\n\n<?xml version="1.0"?><routes></routes>--multipart-path_xml-boundary1234--\n\n ' finally: #yield '\n\n--multipart-path_xml-boundary1234--\n\n' # close database connections self.pgosmdb.close_pgosmdb_connection(pgosmdb_conn) self.pggtfsdb.close_pggtfsdb_connection(pggtfsdb_conn) # destroy WalkOptions object wo.destroy() # destroy shortest path tree if (spt is not None): spt.destroy_no_hash()
def path(self, lat1, lng1, lat2, lng2, transfer_penalty=0, walking_speed=1.0, hill_reluctance=20, narrative=True, jsoncallback=None): t0 = time.time() origin = "osm-%s" % self.osmdb.nearest_node(lat1, lng1)[0] dest = "osm-%s" % self.osmdb.nearest_node(lat2, lng2)[0] endpoint_find_time = time.time() - t0 print origin, dest t0 = time.time() wo = WalkOptions() #wo.transfer_penalty=transfer_penalty #wo.walking_speed=walking_speed wo.walking_speed = 4 wo.walking_overage = 0 wo.hill_reluctance = 20 wo.turn_penalty = 15 edgepayloads = self.ch.shortest_path(origin, dest, State(1, 0), wo) wo.destroy() route_find_time = time.time() - t0 t0 = time.time() names = [] geoms = [] profile = Profile() total_dist = 0 total_elev = 0 if narrative: names, total_dist = get_full_route_narrative( self.osmdb, edgepayloads) for edgepayload in edgepayloads: geom, profile_seg = self.shortcut_cache.get( edgepayload.external_id) #geom = get_ep_geom( self.osmdb, edgepayload ) #profile_seg = get_ep_profile( self.profiledb, edgepayload ) geoms.extend(geom) profile.add(profile_seg) route_desc_time = time.time() - t0 ret = json.dumps( (names, encode_pairs([(lat, lon) for lon, lat in geoms]), profile.concat(300), { 'route_find_time': route_find_time, 'route_desc_time': route_desc_time, 'endpoint_find_time': endpoint_find_time, }, { 'total_dist': total_dist, 'total_elev': total_elev })) if jsoncallback: return "%s(%s)" % (jsoncallback, ret) else: return ret