def create_way_segment_by_id(self, osm_way_id, walking_reverse=False): try: result = DBControl().fetch_data("SELECT tags \ from ways where id = %d" % osm_way_id)[0] except IndexError as e: return {} osm_way_id = int(osm_way_id) tags = self.parse_hstore_column(result['tags']) return self.create_way_segment(osm_way_id, tags, walking_reverse)
def get_route_segment_sub_points(self, routing_table_id, reverse): c_list = DBControl().fetch_data("" \ "SELECT ST_Y(geom) AS lat, ST_X(geom) AS lon " \ "FROM (" \ "SELECT ST_PointN(geom_way, generate_series(1, ST_NPoints(geom_way))) AS geom " \ "FROM %s WHERE id = %d) AS points;" \ % (self.temp_routing_table_name, routing_table_id)) if reverse: c_list = c_list[::-1] point_list = [] last_accepted_bearing = geometry.bearing_between_two_points( c_list[0]['lat'], c_list[0]['lon'], c_list[1]['lat'], c_list[1]['lon']) for i in range(1, c_list.__len__()-1): new_bearing = geometry.bearing_between_two_points( c_list[i]['lat'], c_list[i]['lon'], c_list[i+1]['lat'], c_list[i+1]['lon']) turn = geometry.turn_between_two_segments( new_bearing, last_accepted_bearing) if turn > 22 and turn < 338: last_accepted_bearing = new_bearing point_list.append(self.poi.create_way_point(-1, c_list[i]['lat'], c_list[i]['lon'], {})) return point_list
def create_way_point_by_id(self, osm_node_id): try: result = DBControl().fetch_data( "SELECT ST_X(geom) as x, ST_Y(geom) as y, tags \ from nodes where id = %d" % osm_node_id)[0] except IndexError as e: return {} osm_node_id = int(osm_node_id) lat = result['y'] lon = result['x'] tags = self.parse_hstore_column(result['tags']) return self.create_way_point(osm_node_id, lat, lon, tags)
def create_poi_by_id(self, poi_id): try: result = DBControl().fetch_data( "SELECT osm_id, ST_X(geom) as x, ST_Y(geom) as y, tags, \ outer_building_id, number_of_entrances \ from poi where id = %d" % poi_id)[0] except IndexError as e: return {} poi_id = int(poi_id) osm_id = int(result['osm_id']) lat = result['y'] lon = result['x'] tags = self.parse_hstore_column(result['tags']) outer_building_id = int(result['outer_building_id']) number_of_entrances = result['number_of_entrances'] return self.create_poi(poi_id, osm_id, lat, lon, tags, outer_building_id, number_of_entrances)
def create_intersection_by_id(self, osm_id): intersection_table = Config().get_param("intersection_table") try: result = DBControl().fetch_data( "SELECT ST_X(geom) as x, ST_Y(geom) as y, name, tags, \ number_of_streets, number_of_streets_with_name, number_of_traffic_signals \ from %s where id = %d" % (intersection_table, osm_id))[0] except IndexError as e: return {} osm_id = int(osm_id) lat = result['y'] lon = result['x'] name = result['name'] tags = self.parse_hstore_column(result['tags']) number_of_streets = result['number_of_streets'] number_of_streets_with_name = result['number_of_streets_with_name'] number_of_traffic_signals = result['number_of_traffic_signals'] return self.create_intersection(osm_id, lat, lon, name, tags, number_of_streets, number_of_streets_with_name, number_of_traffic_signals)
def follow_this_way(self): # set gzip header cherrypy.response.headers['Content-Type'] = 'application/gzip' # create the return tuple return_tuple = {} return_tuple['route'] = [] return_tuple['warning'] = "" return_tuple['error'] = "" translator = Translator(Config().get_param("default_language")) # parse json encoded input input = helper.convert_dict_values_to_utf8( cherrypy.request.json ) # options if input.has_key("options") == False: return_tuple['error'] = translator.translate("message", "no_route_options") return helper.zip_data(return_tuple) elif type(input['options']) != type({}): return_tuple['error'] = translator.translate("message", "no_route_options") return helper.zip_data(return_tuple) options = input['options'] # user language language = "" if options.has_key("language") == True: language = options['language'] # if the user sends a language, which is not german, take the default language setting if language != "de": language = Config().get_param("default_language") # initialize the translator object with the user's choosen language translator = Translator(language) # start point if input.has_key("start_point") == False: return_tuple['error'] = translator.translate("message", "no_start_point") return helper.zip_data(return_tuple) start_point = input['start_point'] if start_point.has_key("name") == False: return_tuple['error'] = translator.translate("message", "start_point_no_name") return helper.zip_data(return_tuple) elif start_point.has_key("lat") == False: return_tuple['error'] = translator.translate("message", "start_point_no_latitude") return helper.zip_data(return_tuple) elif start_point.has_key("lon") == False: return_tuple['error'] = translator.translate("message", "start_point_no_longitude") return helper.zip_data(return_tuple) elif start_point.has_key("type") == False: return_tuple['error'] = translator.translate("message", "start_point_no_type") return helper.zip_data(return_tuple) # further options if options.has_key("way_id") == False: return_tuple['error'] = translator.translate("message", "no_way_id") return helper.zip_data(return_tuple) if options.has_key("bearing") == False: return_tuple['error'] = translator.translate("message", "no_bearing_value") return helper.zip_data(return_tuple) add_all_intersections = False if options.has_key("add_all_intersections") == True: if options['add_all_intersections'] == "yes": add_all_intersections = True way = DBControl().fetch_data("SELECT nodes from ways where id = %d" % options['way_id']) if way.__len__() == 0: return_tuple['error'] = translator.translate("message", "way_id_invalid") return helper.zip_data(return_tuple) # create session id if options.has_key("session_id") == False: return_tuple['error'] = translator.translate("message", "no_session_id_option") return helper.zip_data(return_tuple) session_id = options['session_id'] # try to cancel prior request if Config().clean_old_session(session_id) == False: return_tuple['error'] = translator.translate("message", "old_request_still_running") return helper.zip_data(return_tuple) if Config().number_of_session_ids() == Config().get_param("thread_pool") - 1: return_tuple['error'] = translator.translate("message", "server_busy") return helper.zip_data(return_tuple) Config().add_session_id(session_id) # get a route route_logger = RouteLogger("routes", "%s---way_id.%s" % (start_point['name'], options['way_id'])) rfc = RouteFootwayCreator(session_id, route_logger, translator, 1.0, ["big_streets", "small_streets", "paved_ways", "unpaved_ways", "unclassified_ways", "steps"], []) try: route = rfc.follow_this_way(start_point, options['way_id'], options['bearing'], add_all_intersections) except RouteFootwayCreator.FootwayRouteCreationError as e: route_logger.append_to_log("\n----- result -----\ncanceled") Config().confirm_removement_of_session_id(session_id) return_tuple['route'] = [] return_tuple['error'] = "%s" % e return helper.zip_data(return_tuple) # return calculated route return_tuple['route'] = route return_tuple['description'] = rfc.get_route_description( return_tuple['route'] ) route_logger.append_to_log("\n----- result -----\n") route_logger.append_to_log( json.dumps( return_tuple['route'], indent=4, encoding="utf-8") + "\n----- end of route -----\n") # convert return_tuple to json and zip it, before returning Config().confirm_removement_of_session_id(session_id) return helper.zip_data(return_tuple)
def follow_this_way(self): # set gzip header cherrypy.response.headers['Content-Type'] = 'application/gzip' # create the return tuple return_tuple = {} return_tuple['route'] = [] return_tuple['warning'] = "" return_tuple['error'] = "" translator = Translator(Config().get_param("default_language")) # parse json encoded input input = helper.convert_dict_values_to_utf8(cherrypy.request.json) # options if input.has_key("options") == False: return_tuple['error'] = translator.translate( "message", "no_route_options") return helper.zip_data(return_tuple) elif type(input['options']) != type({}): return_tuple['error'] = translator.translate( "message", "no_route_options") return helper.zip_data(return_tuple) options = input['options'] # user language language = "" if options.has_key("language") == True: language = options['language'] # if the user sends a language, which is not german, take the default language setting if language != "de": language = Config().get_param("default_language") # initialize the translator object with the user's choosen language translator = Translator(language) # start point if input.has_key("start_point") == False: return_tuple['error'] = translator.translate( "message", "no_start_point") return helper.zip_data(return_tuple) start_point = input['start_point'] if start_point.has_key("name") == False: return_tuple['error'] = translator.translate( "message", "start_point_no_name") return helper.zip_data(return_tuple) elif start_point.has_key("lat") == False: return_tuple['error'] = translator.translate( "message", "start_point_no_latitude") return helper.zip_data(return_tuple) elif start_point.has_key("lon") == False: return_tuple['error'] = translator.translate( "message", "start_point_no_longitude") return helper.zip_data(return_tuple) elif start_point.has_key("type") == False: return_tuple['error'] = translator.translate( "message", "start_point_no_type") return helper.zip_data(return_tuple) # further options if options.has_key("way_id") == False: return_tuple['error'] = translator.translate( "message", "no_way_id") return helper.zip_data(return_tuple) if options.has_key("bearing") == False: return_tuple['error'] = translator.translate( "message", "no_bearing_value") return helper.zip_data(return_tuple) add_all_intersections = False if options.has_key("add_all_intersections") == True: if options['add_all_intersections'] == "yes": add_all_intersections = True way = DBControl().fetch_data("SELECT nodes from ways where id = %d" % options['way_id']) if way.__len__() == 0: return_tuple['error'] = translator.translate( "message", "way_id_invalid") return helper.zip_data(return_tuple) # create session id if options.has_key("session_id") == False: return_tuple['error'] = translator.translate( "message", "no_session_id_option") return helper.zip_data(return_tuple) session_id = options['session_id'] # try to cancel prior request if Config().clean_old_session(session_id) == False: return_tuple['error'] = translator.translate( "message", "old_request_still_running") return helper.zip_data(return_tuple) if Config().number_of_session_ids( ) == Config().get_param("thread_pool") - 1: return_tuple['error'] = translator.translate( "message", "server_busy") return helper.zip_data(return_tuple) Config().add_session_id(session_id) # get a route route_logger = RouteLogger( "routes", "%s---way_id.%s" % (start_point['name'], options['way_id'])) rfc = RouteFootwayCreator(session_id, route_logger, translator, 1.0, [ "big_streets", "small_streets", "paved_ways", "unpaved_ways", "unclassified_ways", "steps" ], []) try: route = rfc.follow_this_way(start_point, options['way_id'], options['bearing'], add_all_intersections) except RouteFootwayCreator.FootwayRouteCreationError as e: route_logger.append_to_log("\n----- result -----\ncanceled") Config().confirm_removement_of_session_id(session_id) return_tuple['route'] = [] return_tuple['error'] = "%s" % e return helper.zip_data(return_tuple) # return calculated route return_tuple['route'] = route return_tuple['description'] = rfc.get_route_description( return_tuple['route']) route_logger.append_to_log("\n----- result -----\n") route_logger.append_to_log( json.dumps(return_tuple['route'], indent=4, encoding="utf-8") + "\n----- end of route -----\n") # convert return_tuple to json and zip it, before returning Config().confirm_removement_of_session_id(session_id) return helper.zip_data(return_tuple)
def find_footway_route(self, start_point, dest_point): print "footway route creator" # a few helper variables t1 = time.time() self.route = [] last_target_id = -1 reverse = False # check for cancel command if Config().has_session_id_to_remove(self.session_id): raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) # create temporary routing table distance_between_start_and_destination = geometry.distance_between_two_points( start_point['lat'], start_point['lon'], dest_point['lat'], dest_point['lon']) print "radius = %d" % distance_between_start_and_destination center_point = geometry.get_center_point( start_point['lat'], start_point['lon'], dest_point['lat'], dest_point['lon']) boundaries = geometry.get_boundary_box(center_point['lat'], center_point['lon'], self.minimum_radius + int(distance_between_start_and_destination / 2)) # create temp table DBControl().send_data("" \ "DROP TABLE IF EXISTS %s;" \ "CREATE TABLE %s AS SELECT * FROM %s LIMIT 0;" \ "INSERT INTO %s " \ "SELECT * from %s " \ "WHERE geom_way && ST_MakeEnvelope(%f, %f, %f, %f);" % (self.temp_routing_table_name, self.temp_routing_table_name, self.routing_table_name, self.temp_routing_table_name, self.routing_table_name, boundaries['left'], boundaries['bottom'], boundaries['right'], boundaries['top'])) # check if temp routing table is empty number_of_table_rows = DBControl().fetch_data("SELECT count(*) from %s" \ % self.temp_routing_table_name)[0]['count'] if number_of_table_rows == 0: DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) self.route_logger.append_to_log("Routing table too small", True) raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("footway_creator", "foot_route_creation_failed")) # adapt cost column t11 = time.time() # weight list for index, weight in enumerate(self.way_class_weight_list): DBControl().send_data("" \ "UPDATE %s SET cost=km*%d where kmh = %d;" \ % (self.temp_routing_table_name, weight, (index+1)) ) # blocked ways DBControl().send_data("" \ "UPDATE %s SET cost=km*(-1) WHERE osm_id = ANY('{%s}');" \ % (self.temp_routing_table_name, ','.join(str(x) for x in self.blocked_ways)) ) # add table index and recreate source and target columns t12 = time.time() DBControl().send_data("" \ "ALTER TABLE ONLY %s ADD CONSTRAINT pkey_%s PRIMARY KEY (id);" \ "CREATE INDEX idx_%s_source ON %s USING btree (source);" \ "CREATE INDEX idx_%s_target ON %s USING btree (target);" \ "CREATE INDEX idx_%s_osm_source_id ON %s USING btree (osm_source_id);" \ "CREATE INDEX idx_%s_osm_target_id ON %s USING btree (osm_target_id);" \ "CREATE INDEX idx_%s_geom_way ON %s USING gist (geom_way);" \ "ALTER TABLE %s CLUSTER ON idx_%s_geom_way;" \ "SELECT recreate_vertex_of_routing_table('%s');" \ "ANALYZE %s;" \ % (self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name, self.temp_routing_table_name)) t2 = time.time() self.route_logger.append_to_log("Temp table creation: %.2f (%.2f / %.2f / %.2f\nnumber of rows = %d" \ % (t2-t1, t11-t1, t12-t11, t2-t12, number_of_table_rows), True) # check for cancel command if Config().has_session_id_to_remove(self.session_id): DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) # get start and destination vertex start_vertex_list = self.get_nearest_vertex( start_point['lat'], start_point['lon']) if start_vertex_list.__len__() == 0 or Config().has_session_id_to_remove(self.session_id): DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) if start_vertex_list.__len__() == 0: self.route_logger.append_to_log("Found no start vertex", True) raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("footway_creator", "foot_route_creation_failed")) else: raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) dest_vertex_list = self.get_nearest_vertex( dest_point['lat'], dest_point['lon']) if dest_vertex_list.__len__() == 0 or Config().has_session_id_to_remove(self.session_id): DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) if dest_vertex_list.__len__(): self.route_logger.append_to_log("Found no destination vertex", True) raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("footway_creator", "foot_route_creation_failed")) else: raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) t3 = time.time() # check for cancel command if Config().has_session_id_to_remove(self.session_id): DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) # route calculation best_route = RouteFootwayCreator.RawRoute([], None, None) max_vertex_list_length = start_vertex_list.__len__() if max_vertex_list_length < dest_vertex_list.__len__(): max_vertex_list_length = dest_vertex_list.__len__() print "length = %d (%d / %d)" % (max_vertex_list_length, start_vertex_list.__len__(), dest_vertex_list.__len__()) for x in range(0, max_vertex_list_length): for y in range(0, x+1): if x < start_vertex_list.__len__() and y < dest_vertex_list.__len__() \ and best_route.cost == 1000000: result = DBControl().fetch_data("" \ "SELECT seq, id1 AS node, id2 AS edge_id, cost FROM pgr_dijkstra(" \ "'select id, source, target, cost from %s', %d, %d, false, false)" \ % (self.temp_routing_table_name, start_vertex_list[x].point_id, dest_vertex_list[y].point_id)) if any(result): best_route = RouteFootwayCreator.RawRoute(result, start_vertex_list[x], dest_vertex_list[y]) self.route_logger.append_to_log( "%d %d Cost: %.2f\n start: %s\n dest: %s" % (x, y, best_route.cost, start_vertex_list[x].__str__(), dest_vertex_list[y].__str__()), True) if y < start_vertex_list.__len__() and x < dest_vertex_list.__len__() \ and x != y and best_route.cost == 1000000: result = DBControl().fetch_data("" \ "SELECT seq, id1 AS node, id2 AS edge_id, cost FROM pgr_dijkstra(" \ "'select id, source, target, cost from %s', %d, %d, false, false)" \ % (self.temp_routing_table_name, start_vertex_list[y].point_id, dest_vertex_list[x].point_id)) if any(result): best_route = RouteFootwayCreator.RawRoute(result, start_vertex_list[y], dest_vertex_list[x]) self.route_logger.append_to_log( "%d %d Cost: %.2f\n start: %s\n dest: %s" % (y, x, best_route.cost, start_vertex_list[y].__str__(), dest_vertex_list[x].__str__()), True) if Config().has_session_id_to_remove(self.session_id): DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) if best_route.cost == 1000000: result = DBControl().fetch_data("" \ "SELECT seq, id1 AS node, id2 AS edge_id, cost FROM pgr_dijkstra(" \ "'select id, source, target, km AS cost from %s WHERE kmh != 7', %d, %d, false, false)" \ % (self.temp_routing_table_name, start_vertex_list[0].point_id, dest_vertex_list[0].point_id)) DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) if any(result): raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("footway_creator", "foot_route_creation_failed_way_classes_missing")) else: raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "foot_route_creation_failed_no_existing_way")) t4 = time.time() self.route_logger.append_to_log("routing algorithm: %.2f" % (t4-t3), True) for r in best_route.route: if r['edge_id'] == -1: continue part = DBControl().fetch_data("SELECT * from %s where id=%d" \ % (self.temp_routing_table_name, r['edge_id']))[0] # exception for the first route segment # add start point of route first if part['source'] == best_route.start_vertex_tuple.point_id: print "start point added" # check if current point is an intersection next_point = self.poi.create_intersection_by_id(part['osm_source_id']) if next_point == {}: next_point = self.poi.create_way_point_by_id(part['osm_source_id']) self.route.append(next_point) last_target_id = part['source'] elif part['target'] == best_route.start_vertex_tuple.point_id: print "target point added" # check if current point is an intersection next_point = self.poi.create_intersection_by_id(part['osm_target_id']) if next_point == {}: next_point = self.poi.create_way_point_by_id(part['osm_target_id']) self.route.append(next_point) last_target_id = part['target'] # create next point if last_target_id == part['source']: next_point = self.poi.create_intersection_by_id(part['osm_target_id']) if next_point == {}: next_point = self.poi.create_way_point_by_id(part['osm_target_id']) reverse = False last_target_id = part['target'] else: next_point = self.poi.create_intersection_by_id(part['osm_source_id']) if next_point == {}: next_point = self.poi.create_way_point_by_id(part['osm_source_id']) reverse = True last_target_id = part['source'] # create next segment next_segment = self.poi.create_way_segment_by_id(part['osm_id'], reverse ) next_segment['way_class'] = part['kmh'] for point in self.get_route_segment_sub_points(part['id'], reverse) + [next_point]: self.add_point_to_route(point, next_segment.copy()) # check for cancel command if Config().has_session_id_to_remove(self.session_id): raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) t5 = time.time() self.route_logger.append_to_log( json.dumps( self.route, indent=4, encoding="utf-8") ) self.route_logger.append_to_log("\n-------------\n") # if no route was found, just use the direct connection between start and destination if self.route.__len__() <= 1: segment = {"name":self.translator.translate("footway_creator", "direct_connection"), "type":"footway", "sub_type":"", "way_id":-1} segment['bearing'] = geometry.bearing_between_two_points( start_point['lat'], start_point['lon'], dest_point['lat'], dest_point['lon']) segment['distance'] = geometry.distance_between_two_points( start_point['lat'], start_point['lon'], dest_point['lat'], dest_point['lon']) self.route.append(start_point) self.route.append(segment) self.route.append(dest_point) DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) return self.route # add start point first_segment = None distance_start_p0 = geometry.distance_between_two_points( start_point['lat'], start_point['lon'], self.route[0]['lat'], self.route[0]['lon']) bearing_start_p0 = geometry.bearing_between_two_points( start_point['lat'], start_point['lon'], self.route[0]['lat'], self.route[0]['lon']) bearing_p0_p1 = self.route[1]['bearing'] turn = geometry.turn_between_two_segments( bearing_p0_p1, bearing_start_p0) print "start: turn = %d, distance = %d" % (turn, distance_start_p0) print "start tuple: %s" % best_route.start_vertex_tuple.__str__() if distance_start_p0 <= 5: print "small dist, replaced start point" self.route[0] = start_point elif best_route.start_vertex_tuple.way_distance <= 5 \ or (best_route.start_vertex_tuple.way_class in [1,2] and best_route.start_vertex_tuple.way_distance <= 15): if turn >= 158 and turn <= 202: print "replaced first intersection with start point" self.route[1]['distance'] -= distance_start_p0 self.route[0] = start_point elif self.important_intersection(self.route[0]) == False \ and (turn <= 22 or turn >= 338): print "deleted first intersection, not important + straight ahead" self.route[1]['distance'] += distance_start_p0 self.route[0] = start_point else: print "added known first segment" first_segment = self.poi.create_way_segment_by_id( best_route.start_vertex_tuple.way_id) else: print "added placeholder first segment" first_segment = {"name":self.translator.translate("footway_creator", "first_segment"), "type":"footway", "sub_type":"", "way_id":-1, "pois":[]} # should we add a first segment? if first_segment != None: print "really added" self.route[0]['turn'] = turn first_segment['bearing'] = bearing_start_p0 first_segment['distance'] = distance_start_p0 self.route.insert(0, first_segment) self.route.insert(0, start_point) # destination point distance_plast_dest = geometry.distance_between_two_points( self.route[-1]['lat'], self.route[-1]['lon'], dest_point['lat'], dest_point['lon']) bearing_plast_dest = geometry.bearing_between_two_points( self.route[-1]['lat'], self.route[-1]['lon'], dest_point['lat'], dest_point['lon']) turn = geometry.turn_between_two_segments( bearing_plast_dest, self.route[-2]['bearing']) print "destination: turn = %d, distance = %d" % (turn, distance_plast_dest) print "dest tuple: %s" % best_route.dest_vertex_tuple.__str__() if distance_plast_dest <= 5: print "small dist, replaced dest point" self.route[-1] = dest_point elif best_route.dest_vertex_tuple.way_distance <= 5 \ or (best_route.dest_vertex_tuple.way_class in [1,2] and best_route.dest_vertex_tuple.way_distance <= 15): if turn >= 158 and turn <= 202: # delete last route point, if you should turn around print "replaced last intersection with destination point, turn around" self.route[-2]['distance'] -= distance_plast_dest self.route[-1] = dest_point elif self.important_intersection(self.route[-1]) == False \ and (turn <= 22 or turn >= 338): print "deleted last intersection, not important + straight ahead" self.route[-2]['distance'] += distance_plast_dest self.route[-1] = dest_point else: print "added known last segment" dest_segment = self.poi.create_way_segment_by_id( best_route.dest_vertex_tuple.way_id) self.add_point_to_route(dest_point, dest_segment) else: print "added placeholder last segment" dest_segment = {"name":self.translator.translate("footway_creator", "last_segment"), "type":"footway", "sub_type":"", "way_id":-1, "pois":[]} self.add_point_to_route(dest_point, dest_segment) t6 = time.time() # print time overview DBControl().send_data("DROP TABLE %s;" % self.temp_routing_table_name) self.route_logger.append_to_log( "1. temp table: %.2f\n" \ "2. vertex calculation: %.2f\n" \ "3. route calculation: %.2f\n" \ "4. add route points: %.2f\n" \ "5. add start and destination: %.2f\n" \ "summary: %.2f" \ % (t2-t1, t3-t2, t4-t3, t5-t4, t6-t5, t6-t1), True) return self.route
def get_nearest_vertex(self, lat, lon): start = time.time() # get vertex of nearest big street or -1 if noone is available try: big_street_vertex = DBControl().fetch_data("" \ "SELECT source from %s " \ "WHERE kmh = ANY('{1,2}') AND osm_name != ''" \ "order by ST_DISTANCE(geom_way::geography, 'POINT(%f %f)'::geography) " \ "limit 1;" \ % (self.temp_routing_table_name, lon, lat))[0]['source'] except IndexError as e: big_street_vertex = -1 t1 = time.time() # get nearest way segments nearest_lines = DBControl().fetch_data("\ SELECT id, osm_id, osm_name, osm_source_id, osm_target_id, source, target, kmh as type, x1, y1, x2, y2, \ ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography) as way_distance \ from %s WHERE kmh != 7 AND get_bit(flags::bit(16), 5) = 0 \ ORDER BY ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography) LIMIT 50" \ % (lon, lat, self.temp_routing_table_name, lon, lat)) # try to prefer railways if the user must cross them to reach destination if big_street_vertex > -1: try: nearest_railway = DBControl().fetch_data("\ SELECT id, osm_id, osm_name, osm_source_id, osm_target_id, source, target, kmh as type, x1, y1, x2, y2, \ ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography) as way_distance \ from %s \ WHERE (clazz = 18 OR clazz = 19) \ AND ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography) < 5.0 \ ORDER BY ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography) LIMIT 1" \ % (lon, lat, self.temp_routing_table_name, lon, lat, lon, lat))[0] # which point of the closest way segment is closer to the given start point source_dist = geometry.distance_between_two_points_as_float( nearest_lines[0]['y1'], nearest_lines[0]['x1'], lat, lon) target_dist = geometry.distance_between_two_points_as_float( nearest_lines[0]['y2'], nearest_lines[0]['x2'], lat, lon) if source_dist < target_dist: nearest_lat = nearest_lines[0]['y1'] nearest_lon = nearest_lines[0]['x1'] else: nearest_lat = nearest_lines[0]['y2'] nearest_lon = nearest_lines[0]['x2'] # test for impassable railway, if exists, add priviously found way, else # catch IndexError exception nearest_intersecting = DBControl().fetch_data("\ SELECT * FROM %s \ WHERE (clazz = 18 OR clazz = 19)AND osm_id != %d \ AND ST_Intersects(geom_way, \ ST_SetSRID(ST_MakeLine(ST_MakePoint(%f, %f), ST_MakePoint(%f, %f)), 4326)) = 't'" \ % (self.temp_routing_table_name, nearest_railway['osm_id'], lon, lat, nearest_lon, nearest_lat))[0] print "jup %f %f" % (nearest_lon, nearest_lat) nearest_lines.insert(0, nearest_railway) except IndexError as e: pass # try to prefer streets with a max distance of 10 meters try: nearest_street = DBControl().fetch_data("\ SELECT id, osm_id, osm_name, osm_source_id, osm_target_id, source, target, kmh as type, x1, y1, x2, y2, \ ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography) as way_distance \ from %s \ WHERE kmh != 7 AND osm_name != '' \ AND ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography) < 10.0 \ ORDER BY ST_Distance(geom_way::geography, 'POINT(%f %f)'::geography)" \ % (lon, lat, self.temp_routing_table_name, lon, lat, lon, lat))[0] if nearest_lines[0]['type'] == 7: nearest_lines.insert(1, nearest_street) else: nearest_lines.insert(0, nearest_street) except IndexError as e: pass t2 = time.time() tuple_list = [] for index, line in enumerate(nearest_lines): # check, if source or target vertex of found edge is closer source_dist = geometry.distance_between_two_points_as_float( line['y1'], line['x1'], lat, lon) target_dist = geometry.distance_between_two_points_as_float( line['y2'], line['x2'], lat, lon) if source_dist < target_dist: tuple = RouteFootwayCreator.VertexTuple(line['source'], source_dist, line['osm_id'], line['type'], line['way_distance'], line['osm_name']) else: tuple = RouteFootwayCreator.VertexTuple(line['target'], target_dist, line['osm_id'], line['type'], line['way_distance'], line['osm_name']) if index < 7: print "id = %d; dist = %d: %d/%d, %d / %s (%d)" % (tuple.point_id, line['way_distance'], source_dist, target_dist, line['type'], line['osm_name'], line['osm_id']) # add id to id list if not any(x for x in tuple_list if x.point_id == tuple.point_id): # check if the way is connected to the main street network # but only if we found a big intersection # otherwise thake the id without verification if big_street_vertex == -1: tuple_list.append(tuple) else: raw_route = DBControl().fetch_data("" \ "SELECT seq, id1 AS node, id2 AS edge_id, cost FROM pgr_dijkstra(" \ "'select id, source, target, km as cost from %s WHERE kmh != 7', %d, %d, false, false)" \ % (self.temp_routing_table_name, tuple.point_id, big_street_vertex)) if any(raw_route): tuple_list.append(tuple) # break if the next point is more than 100 meters away or if you already have # at least 15 ids if len(tuple_list) >= 5 \ and (line['way_distance'] > 100 or len(tuple_list) >= 15): break end = time.time() print "%.2f, %.2f, %.2f" % (t1-start, t2-t1, end-t2) print "find vertex, time elapsed: %.2f" % (end-start) return tuple_list
def follow_this_way(self, start_point, way_id, bearing, add_all_intersections): self.route = [] way = DBControl().fetch_data("SELECT nodes from ways where id = %d" % way_id)[0] # check for cancel command if Config().has_session_id_to_remove(self.session_id): raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) # find nearest way point min_dist = 1000000 id_index = 0 i = 0 for id in way['nodes']: wp = DBControl().fetch_data("SELECT ST_y(geom) as lat, ST_X(geom) as lon from nodes where id = %d" % id)[0] dist = geometry.distance_between_two_points(start_point['lat'], start_point['lon'], wp['lat'], wp['lon']) if dist < min_dist: min_dist = dist id_index = i i += 1 if id_index == 0: prev = DBControl().fetch_data("SELECT ST_y(geom) as lat, ST_X(geom) as lon from nodes where id = %d" % way['nodes'][id_index])[0] next = DBControl().fetch_data("SELECT ST_y(geom) as lat, ST_X(geom) as lon from nodes where id = %d" % way['nodes'][id_index+1])[0] else: prev = DBControl().fetch_data("SELECT ST_y(geom) as lat, ST_X(geom) as lon from nodes where id = %d" % way['nodes'][id_index-1])[0] next = DBControl().fetch_data("SELECT ST_y(geom) as lat, ST_X(geom) as lon from nodes where id = %d" % way['nodes'][id_index])[0] bearing_difference = geometry.bearing_between_two_points(prev['lat'], prev['lon'], next['lat'], next['lon']) - bearing if bearing_difference < 0: bearing_difference += 360 if bearing_difference < 90 or bearing_difference >= 270: for index in range( id_index, way['nodes'].__len__()): next_point = self.poi.create_intersection_by_id(way['nodes'][index]) if next_point == {}: next_point = self.poi.create_way_point_by_id(way['nodes'][index]) next_segment = self.poi.create_way_segment_by_id(way_id) self.add_point_to_route(next_point, next_segment, add_all_intersections) last_node_id = way['nodes'][-1] else: for index in range( id_index, -1, -1): next_point = self.poi.create_intersection_by_id(way['nodes'][index]) if next_point == {}: next_point = self.poi.create_way_point_by_id(way['nodes'][index]) next_segment = self.poi.create_way_segment_by_id(way_id, True) self.add_point_to_route(next_point, next_segment, add_all_intersections) last_node_id = way['nodes'][0] # check for cancel command if Config().has_session_id_to_remove(self.session_id): raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) last_way_properties = self.poi.create_way_segment_by_id(way_id) while True: found_next_part = False result = DBControl().fetch_data("SELECT w.id, w.nodes \ from ways w join way_nodes wn on w.id = wn.way_id \ where wn.node_id = %d and wn.way_id != %d" % (last_node_id, last_way_properties['way_id'])) if result.__len__() == 0: break for way in result: next_way_properties = self.poi.create_way_segment_by_id(way['id']) if last_way_properties['name'] != next_way_properties['name']: continue if last_node_id == way['nodes'][0]: for index in range(1, way['nodes'].__len__()): next_point = self.poi.create_intersection_by_id(way['nodes'][index]) if next_point == {}: next_point = self.poi.create_way_point_by_id(way['nodes'][index]) next_segment = self.poi.create_way_segment_by_id( last_way_properties['way_id']) self.add_point_to_route(next_point, next_segment, add_all_intersections) last_node_id = way['nodes'][-1] last_way_properties = next_way_properties found_next_part = True break if last_node_id == way['nodes'][-1]: for index in range( way['nodes'].__len__()-2, -1, -1): next_point = self.poi.create_intersection_by_id(way['nodes'][index]) if next_point == {}: next_point = self.poi.create_way_point_by_id(way['nodes'][index]) next_segment = self.poi.create_way_segment_by_id( last_way_properties['way_id'], True) self.add_point_to_route(next_point, next_segment, add_all_intersections) last_node_id = way['nodes'][0] last_way_properties = next_way_properties found_next_part = True break if found_next_part == False: break # check for cancel command if Config().has_session_id_to_remove(self.session_id): raise RouteFootwayCreator.FootwayRouteCreationError( self.translator.translate("message", "process_canceled")) return self.route
def __init__(self, session_id, route_logger_object, translator_object, indirection_factor, allowed_way_classes, blocked_ways): self.session_id = session_id self.route_logger = route_logger_object self.translator = translator_object # routing parameters self.route = [] self.routing_table_name = Config().get_param("routing_table") self.temp_routing_table_name = "tmp_routing_%s" \ % re.sub(r'[^a-zA-Z0-9]', '', self.session_id) self.intersections_table_name = Config().get_param("intersection_table") self.poi = POI(session_id, translator_object) self.minimum_radius = 600 self.blocked_ways = blocked_ways # table column name for given indirection factor factor_column_name = "x1" if indirection_factor == 4.0: factor_column_name = "x4" elif indirection_factor == 3.0: factor_column_name = "x3" elif indirection_factor == 2.0: factor_column_name = "x2" elif indirection_factor == 1.5: factor_column_name = "x1_5" # way class weights list # way_class_weights table id's: # 1 = good way # 2 = neutral way # 3 = bad way # 4 = impassable way weight_list = DBControl().fetch_data("SELECT %s as weight \ from way_class_weights;" % factor_column_name) # way classes: find them in the kmh column of the routing table # wcw_id 1 -- list index 0 = class 1: big, middle and unknown streets # wcw_id 0 -- list index 1 = class 2: small streets # wcw_id 1 -- list index 2 = class 3: paved ways # wcw_id 2 -- list index 3 = class 4: unpaved ways # wcw_id 2 -- list index 4 = class 5: unclassified ways # wcw_id 2 -- list index 5 = class 6: steps # wcw_id 3 -- list index 6 = class 7: impassable ways # initialize with all classes impassable self.way_class_weight_list = [ weight_list[3]['weight'] for x in range(7)] if allowed_way_classes.__contains__("big_streets"): # big and middle streets: neutral self.way_class_weight_list[0] = weight_list[1]['weight'] if allowed_way_classes.__contains__("small_streets"): # small streets: good self.way_class_weight_list[1] = weight_list[0]['weight'] if allowed_way_classes.__contains__("paved_ways"): # paved ways: neutral self.way_class_weight_list[2] = weight_list[1]['weight'] if allowed_way_classes.__contains__("unpaved_ways"): # unpaved ways: bad self.way_class_weight_list[3] = weight_list[2]['weight'] if allowed_way_classes.__contains__("unclassified_ways"): # unclassified ways: bad self.way_class_weight_list[4] = weight_list[2]['weight'] if allowed_way_classes.__contains__("steps"): # steps: bad self.way_class_weight_list[5] = weight_list[2]['weight'] # multiplication factor for way segment length = 100 - weight for index, weight in enumerate(self.way_class_weight_list): self.way_class_weight_list[index] = 100 - weight self.route_logger.append_to_log(self.way_class_weight_list, True)
def main(): # setting variables tag, name, password, url_limit, post_limit, browser, executable, db_batch, from_code, stop_code, implicit_wait, \ driver_options, min_scroll_wait, max_scroll_wait, enrich, proxy = arg_parser() # setting log file logging.basicConfig(filename=DEFAULT_LOG_FILE_PATH, format=DEFAULT_LOG_FILE_FORMAT, level=logging.INFO) # scraping urls and posts driver_set_up = (name, password, browser, implicit_wait, executable, proxy, driver_options) driver = Driver(*driver_set_up) logging.info('driver object - set') htp = HashTagPage(tag, driver, max_scroll_wait, min_scroll_wait, from_code, stop_code, url_limit) # set hash tage page instance for scrapping logging.info('HashTagPage object - set') # setting up DB connection dbc = DBControl() # scrapping for urls for url_batch in htp.shortcode_batch_generator(): dbc.insert_shortcodes(url_batch) logging.info('done short code scrapping step') ps = PostScraper(driver) records = [] logging.info( 'connection to SQL server for post scraping and update step - successful' ) logging.info('set limit value for post scrapping: {}'.format(post_limit)) while True: batch = dbc.shortcodes_list_for_scraping(db_batch) if any([not batch, ps.posts_scraped >= post_limit]): dbc.check_post_to_scrap_sanity() break post_len2add = len(batch) + ps.posts_scraped if post_len2add > post_limit: delta = post_len2add - post_limit batch, return_batch = batch[:delta], batch[delta:] if len(return_batch) > 0: dbc.unconfirm_end_scraping_for_shortcodes(return_batch) records += ps.post_scraping(batch) ps.posts_scraped += len(batch) if len(records) >= POST_LENGTH_TO_COMMIT: dbc.insert_posts(records) records = [] driver.driver.close() logging.info('done post scraping step') logging.info('start translation step') post_to_translate = dbc.select_post_to_translate(number=enrich) for shortcode in post_to_translate: text = dbc.select_post_text_to_translate(shortcode) pt = PostText(text[0]) pt.analyze_sentiment() dbc.update_translation_and_sentiment(shortcode, pt.language, pt.translation, pt.sentiment) logging.info('end translation step')
def create_station(self, station_id, osm_id, lat, lon, tags, outer_building_id, number_of_entrances, number_of_lines): station = {} if type(station_id) is not int or type(lat) is not float or type( lon) is not float or type(tags) is not dict or type( outer_building_id) is not int or type( number_of_entrances) is not int or type( number_of_lines) is not int: return poi station = self.create_poi(station_id, osm_id, lat, lon, tags, outer_building_id, number_of_entrances) if station == {}: return station # parse tags station['type'] = "station" station['sub_type'] = self.translator.translate( "public_transport", "unknown") station['vehicles'] = [] if tags.has_key("highway") and tags['highway'] == "bus_stop": if "bus" not in station['vehicles']: station['vehicles'].append("bus") if tags.has_key("railway") and tags['railway'] == "tram_stop": if "tram" not in station['vehicles']: station['vehicles'].append("tram") if tags.has_key("train") and tags['train'] == "yes": if "train" not in station['vehicles']: station['vehicles'].append("train") if tags.has_key("subway") and tags['subway'] == "yes": if "subway" not in station['vehicles']: station['vehicles'].append("subway") if tags.has_key("monorail") and tags['monorail'] == "yes": if "monorail" not in station['vehicles']: station['vehicles'].append("monorail") if tags.has_key("light_rail") and tags['light_rail'] == "yes": if "light_rail" not in station['vehicles']: station['vehicles'].append("light_rail") if tags.has_key("bus") and tags['bus'] == "yes": if "bus" not in station['vehicles']: station['vehicles'].append("bus") if tags.has_key("tram") and tags['tram'] == "yes": if "tram" not in station['vehicles']: station['vehicles'].append("tram") if tags.has_key("aerialway") and tags['aerialway'] == "yes": if "aerialway" not in station['vehicles']: station['vehicles'].append("aerialway") if tags.has_key("ferry") and tags['ferry'] == "yes": if "ferry" not in station['vehicles']: station['vehicles'].append("ferry") if tags.has_key("railway") and (tags['railway'] == "station" or tags['railway'] == "halt"): if tags.has_key("station") and tags['station'] == "subway": if "subway" not in station['vehicles']: station['vehicles'].append("subway") elif tags.has_key("station") and tags['station'] == "light_rail": if "light_rail" not in station['vehicles']: station['vehicles'].append("light_rail") else: if station['vehicles'].__len__() == 0: station['vehicles'].append("train") if station['vehicles'].__len__() > 0: station['sub_type'] = "" for vehicle in station['vehicles']: station['sub_type'] += "%s, " % self.translator.translate( "public_transport", vehicle) if station['sub_type'].endswith(", "): station['sub_type'] = station['sub_type'][0:station['sub_type'] .__len__() - 2] # transport lines station['lines'] = [] if number_of_lines > 0: result = DBControl().fetch_data( "SELECT DISTINCT line, direction, type \ from transport_lines where poi_id = %d ORDER BY type" % station_id) for row in result: if not row.has_key("line"): continue line = {"nr": row['line'], "to": ""} if row.has_key("direction") and row['direction'] != None: line['to'] = row['direction'] station['lines'].append(line) return station
def create_poi(self, poi_id, osm_id, lat, lon, tags, outer_building_id, number_of_entrances): poi = {} if type(poi_id) is not int or type(lat) is not float or type(lon) is not float \ or type(tags) is not dict or type(outer_building_id) is not int or type(number_of_entrances) is not int: return poi poi = self.create_way_point(osm_id, lat, lon, tags) if poi == {}: return poi # parse tags # address address1 = "" if tags.has_key("addr:street") and tags.has_key("addr:housenumber"): address1 += "%s %s" % (tags['addr:street'], tags['addr:housenumber']) if tags.has_key("addr:postcode"): address1 += ", %s" % tags['addr:postcode'] if tags.has_key("addr:city"): address1 += " %s" % tags['addr:city'] address2 = "" if tags.has_key("street") and tags.has_key("housenumber"): address2 += "%s %s" % (tags['street'], tags['housenumber']) if tags.has_key("postcode"): address2 += ", %s" % tags['postcode'] if tags.has_key("city"): address2 += " %s" % tags['city'] if address1.__len__() > 0 or address2.__len__() > 0: if address1.__len__() < address2.__len__(): poi['address'] = address2 else: poi['address'] = address1 # type and subtype poi['type'] = "poi" poi['sub_type'] = "" if tags.has_key("amenity"): if tags.has_key("cuisine"): poi['sub_type'] = "%s (%s)" % ( self.translator.translate("amenity", tags['amenity']), self.translator.translate("cuisine", tags['cuisine'])) elif tags.has_key("vending"): poi['sub_type'] = "%s (%s)" % ( self.translator.translate("amenity", tags['amenity']), self.translator.translate("vending", tags['vending'])) else: poi['sub_type'] = self.translator.translate( "amenity", tags['amenity']) elif tags.has_key("bridge"): poi['sub_type'] = self.translator.translate( "bridge", tags['bridge']) elif tags.has_key("tourism"): poi['sub_type'] = self.translator.translate( "tourism", tags['tourism']) elif tags.has_key("historic"): poi['sub_type'] = self.translator.translate( "historic", tags['historic']) elif tags.has_key("leisure"): if tags.has_key("sport"): poi['sub_type'] = "%s (%s)" % ( self.translator.translate("leisure", tags['leisure']), self.translator.translate("sport", tags['sport'])) else: poi['sub_type'] = self.translator.translate( "leisure", tags['leisure']) elif tags.has_key("man_made"): poi['sub_type'] = self.translator.translate( "man_made", tags['man_made']) elif tags.has_key("natural"): poi['sub_type'] = self.translator.translate( "natural", tags['natural']) elif tags.has_key("shop"): poi['sub_type'] = self.translator.translate("shop", tags['shop']) elif tags.has_key("aeroway"): poi['sub_type'] = self.translator.translate( "aeroway", tags['aeroway']) elif tags.has_key("building"): if tags['building'] == "yes": poi['sub_type'] = self.translator.translate( "building", "building") else: poi['sub_type'] = self.translator.translate( "building", tags['building']) elif poi.has_key("address") == True: poi['sub_type'] = self.translator.translate("poi", "address") elif tags.has_key("crossing"): poi['sub_type'] = self.translator.translate( "crossing", tags['crossing']) elif tags.has_key("highway") and tags['highway'] == "crossing" \ and tags.has_key("crossing_ref") and tags['crossing_ref'] in ["pelican", "toucan", "zebra"]: poi['sub_type'] = self.translator.translate( "crossing", tags['crossing_ref']) elif tags.has_key("highway") and tags['highway'] == "traffic_signals": poi['sub_type'] = self.translator.translate( "highway", "traffic_signals") elif tags.has_key("railway") and tags['railway'] == "crossing": poi['sub_type'] = self.translator.translate("railway", "crossing") # name if tags.has_key("name"): poi['name'] = tags['name'] elif tags.has_key("description"): poi['name'] = tags['description'] elif tags.has_key("operator"): poi['name'] = tags['operator'] elif tags.has_key("ref"): poi['name'] += " (%s)" % tags['ref'] elif poi.has_key("address"): poi['name'] = poi['address'] else: poi['name'] = poi['sub_type'] # traffic signals attributes if tags.has_key("traffic_signals:sound"): if tags['traffic_signals:sound'] == "no": poi['traffic_signals_sound'] = 0 if tags['traffic_signals:sound'] == "yes": poi['traffic_signals_sound'] = 1 if tags.has_key("traffic_signals:vibration"): if tags['traffic_signals:vibration'] == "no": poi['traffic_signals_vibration'] = 0 if tags['traffic_signals:vibration'] == "yes": poi['traffic_signals_vibration'] = 1 # contact if tags.has_key("contact:website"): poi['website'] = tags['contact:website'] elif tags.has_key("website"): poi['website'] = tags['website'] if tags.has_key("contact:email"): poi['email'] = tags['contact:email'] elif tags.has_key("email"): poi['email'] = tags['email'] if tags.has_key("contact:phone"): poi['phone'] = tags['contact:phone'] elif tags.has_key("phone"): poi['phone'] = tags['phone'] if tags.has_key("opening_hours"): poi['opening_hours'] = tags['opening_hours'] # outer building poi['is_inside'] = {} if outer_building_id > 0: try: result = DBControl().fetch_data( "SELECT ST_X(geom) as x, ST_Y(geom) as y, tags \ from outer_buildings where id = %d" % outer_building_id)[0] lat = result['y'] lon = result['x'] tags = self.parse_hstore_column(result['tags']) poi['is_inside'] = self.create_poi(0, 0, lat, lon, tags, 0, 0) except IndexError as e: poi['is_inside'] = {} # entrances poi['entrance_list'] = [] if number_of_entrances > 0: result = DBControl().fetch_data( "SELECT entrance_id, ST_X(geom) as lon, ST_Y(geom) as lat, label, tags \ from entrances where poi_id = %d ORDER BY class" % poi_id) for row in result: entrance = self.create_way_point( row['entrance_id'], row['lat'], row['lon'], self.parse_hstore_column(row['tags'])) entrance['name'] = self.translator.translate( "entrance", row['label']) entrance['type'] = "poi" entrance['sub_type'] = self.translator.translate( "entrance", "entrance") entrance['entrance'] = row['label'] poi['entrance_list'].append(entrance) return poi
def create_intersection(self, osm_id, lat, lon, name, tags, number_of_streets, number_of_streets_with_name, number_of_traffic_signals): intersection_table = Config().get_param("intersection_table") intersection_table_data = Config().get_param("intersection_data_table") intersection = {} if type(osm_id) is not int or type(lat) is not float or type( lon) is not float or type(name) is not str or type( tags) is not dict or type( number_of_streets) is not int or type( number_of_streets_with_name) is not int or type( number_of_traffic_signals) is not int: return intersection intersection = self.create_way_point(osm_id, lat, lon, tags) if intersection == {}: return intersection # traffic lights intersection['pedestrian_crossing_list'] = [] if number_of_traffic_signals > 0: result = DBControl().fetch_data( "SELECT id, ST_X(geom) as lon, ST_Y(geom) as lat, crossing_street_name, tags \ from pedestrian_crossings where intersection_id = %d" % osm_id) for row in result: signal = self.create_poi(0, int(row['id']), row['lat'], row['lon'], self.parse_hstore_column(row['tags']), 0, 0) if row['crossing_street_name'] != None: signal['name'] += ": %s" % row['crossing_street_name'] intersection['pedestrian_crossing_list'].append(signal) # intersection specific properties intersection['name'] = "" for street in name.split(","): translated_street = self.translator.translate( "highway", street.strip()) if translated_street == street.strip(): translated_street = self.translator.translate( "railway", street.strip()) intersection['name'] += "%s, " % translated_street intersection['name'] = intersection['name'].strip(",") intersection[ 'number_of_streets_with_name'] = number_of_streets_with_name intersection['type'] = "intersection" intersection['sub_type'] = self.translator.translate( "crossing", "unknown") if tags.has_key("crossing"): intersection['sub_type'] = self.translator.translate( "crossing", tags['crossing']) elif tags.has_key("highway") and tags['highway'] == "crossing" \ and tags.has_key("crossing_ref") and tags['crossing_ref'] in ["pelican", "toucan", "zebra"]: intersection['sub_type'] = self.translator.translate( "crossing", tags['crossing_ref']) elif tags.has_key("highway") and tags['highway'] == "traffic_signals": intersection['sub_type'] = self.translator.translate( "highway", "traffic_signals") elif tags.has_key("railway") and tags['railway'] == "crossing": intersection['sub_type'] = self.translator.translate( "railway", "crossing") elif intersection['pedestrian_crossing_list'].__len__() > 0: intersection['sub_type'] = self.translator.translate( "crossing", "traffic_signals") # streets intersection['sub_points'] = [] result = DBControl().fetch_data("\ SELECT way_id, node_id, direction, way_tags, node_tags, \ ST_X(geom) as lon, ST_Y(geom) as lat \ from %s where id = %d" % (intersection_table_data, osm_id)) for street in result: sub_point = self.create_way_point( street['node_id'], street['lat'], street['lon'], self.parse_hstore_column(street['node_tags'])) if street['direction'] == "B": way_segment = self.create_way_segment( street['way_id'], self.parse_hstore_column(street['way_tags']), True) else: way_segment = self.create_way_segment( street['way_id'], self.parse_hstore_column(street['way_tags']), False) for key in way_segment: sub_point[key] = way_segment[key] sub_point[ 'intersection_bearing'] = geometry.bearing_between_two_points( intersection['lat'], intersection['lon'], sub_point['lat'], sub_point['lon']) intersection['sub_points'].append(sub_point) return intersection
def get_poi(self, lat, lon, radius, tag_list, search=""): ts = time.time() poi_list = [] # tags, boundary box and search strings tags = self.create_tags(tag_list) if search != "": # if we search for something, choose a 50 km radius boundaries = geometry.get_boundary_box(lat, lon, 10000) # prepare search strings search = search.replace(" ", "%").lower() search_poi = "(" search_poi += "LOWER(tags->'name') LIKE '%%%s%%' or " % search search_poi += "LOWER(tags->'amenity') LIKE '%%%s%%' or " % search search_poi += "LOWER(tags->'cuisine') LIKE '%%%s%%' or " % search search_poi += "LOWER(tags->'addr:street') LIKE '%%%s%%' or " % search search_poi += "LOWER(tags->'street') LIKE '%%%s%%'" % search search_poi += ")" search_pedestrian_crossings = "LOWER(crossing_street_name) LIKE '%%%s%%'" % search search_other = "LOWER(name) LIKE '%%%s%%'" % search else: boundaries = geometry.get_boundary_box(lat, lon, radius) search_poi = "" search_pedestrian_crossings = "" search_other = "" # intersections if tags['intersection'] != "": t1 = time.time() where_clause = "geom && ST_MakeEnvelope(%f, %f, %f, %f)" \ % (boundaries['left'], boundaries['bottom'], boundaries['right'], boundaries['top']) if tags['intersection'] == "name": # only bigger intersections where_clause += " AND number_of_streets_with_name > 1" elif tags['intersection'] == "other": # only smaller intersections where_clause += " AND number_of_streets_with_name <= 1" # search for something? if search_poi != "": where_clause += " AND %s" % search_other # query data result = DBControl().fetch_data("" \ "SELECT id, ST_X(geom) as lon, ST_Y(geom) as lat, name, tags, number_of_streets, " \ "number_of_streets_with_name, number_of_traffic_signals " \ "FROM %s WHERE %s;" % (Config().get_param("intersection_table"), where_clause)) t2 = time.time() for row in result: intersection_id = int(row['id']) intersection_tags = self.parse_hstore_column(row['tags']) intersection = self.create_intersection( intersection_id, row['lat'], row['lon'], row['name'], intersection_tags, row['number_of_streets'], row['number_of_streets_with_name'], row['number_of_traffic_signals']) poi_list = self.insert_into_poi_list(poi_list, intersection, lat, lon) # prevent accidental queries with more than 500 results if poi_list.__len__() > 500: break # check for cancel command if Config().has_session_id_to_remove(self.session_id): Config().confirm_removement_of_session_id(self.session_id) return t3 = time.time() if self.hide_log_messages == False: print "intersection gesamt = %.2f, dbquery = %.2f, parsing = %.2f" % ( (t3 - t1), (t2 - t1), (t3 - t2)) # stations if tags['station'] != "": t1 = time.time() where_clause = "geom && ST_MakeEnvelope(%f, %f, %f, %f) AND %s" \ % (boundaries['left'], boundaries['bottom'], boundaries['right'], boundaries['top'], tags['station']) if search_poi != "": where_clause += " AND %s" % search_poi result = DBControl().fetch_data("" \ "SELECT id, osm_id, ST_X(geom) as lon, ST_Y(geom) as lat, tags, " \ "outer_building_id, number_of_entrances, number_of_lines " \ "FROM stations WHERE %s;" % where_clause) t2 = time.time() for row in result: station_id = int(row['id']) osm_id = int(row['osm_id']) outer_building_id = int(row['outer_building_id']) station_tags = self.parse_hstore_column(row['tags']) if "name" not in station_tags: # a station without a name is not very usefull continue if "public_transport" not in station_tags: # legacy mode for stations without stop_position existance_check = DBControl().fetch_data("" \ "SELECT exists(SELECT 1 FROM stations WHERE %s " \ "and tags->'name' = '%s' and tags ? 'public_transport') as exists" \ % (where_clause, station_tags['name']))[0] if existance_check['exists']: # the station already is represented by another one with the same name # and a stop_position tag, so skip this one continue station = self.create_station(station_id, osm_id, row['lat'], row['lon'], station_tags, outer_building_id, row['number_of_entrances'], row['number_of_lines']) poi_list = self.insert_into_poi_list(poi_list, station, lat, lon) # prevent accidental queries with more than 500 results if poi_list.__len__() > 500: break # check for cancel command if Config().has_session_id_to_remove(self.session_id): Config().confirm_removement_of_session_id(self.session_id) return t3 = time.time() if self.hide_log_messages == False: print "station gesamt = %.2f, dbquery = %.2f, parsing = %.2f" % ( (t3 - t1), (t2 - t1), (t3 - t2)) # poi if tags['poi'] != "": t1 = time.time() where_clause = "geom && ST_MakeEnvelope(%f, %f, %f, %f) AND %s" \ % (boundaries['left'], boundaries['bottom'], boundaries['right'], boundaries['top'], tags['poi']) if search_poi != "": where_clause += " AND %s" % search_poi result = DBControl().fetch_data("" \ "SELECT id, osm_id, ST_X(geom) as lon, ST_Y(geom) as lat, tags, " \ "outer_building_id, number_of_entrances " \ "FROM poi WHERE %s;" % where_clause) t2 = time.time() for row in result: poi_id = int(row['id']) osm_id = int(row['osm_id']) poi_tags = self.parse_hstore_column(row['tags']) outer_building_id = int(row['outer_building_id']) poi = self.create_poi(poi_id, osm_id, row['lat'], row['lon'], poi_tags, outer_building_id, row['number_of_entrances']) poi_list = self.insert_into_poi_list(poi_list, poi, lat, lon) # prevent accidental queries with more than 500 results if poi_list.__len__() > 500: break # check for cancel command if Config().has_session_id_to_remove(self.session_id): Config().confirm_removement_of_session_id(self.session_id) return t3 = time.time() if self.hide_log_messages == False: print "poi gesamt = %.2f, dbquery = %.2f, parsing = %.2f" % ( (t3 - t1), (t2 - t1), (t3 - t2)) # pedestrian crossings if tags['pedestrian_crossings'] != "": t1 = time.time() where_clause = "geom && ST_MakeEnvelope(%f, %f, %f, %f)" \ % (boundaries['left'], boundaries['bottom'], boundaries['right'], boundaries['top']) if search_poi != "": where_clause += " AND %s" % search_pedestrian_crossings result = DBControl().fetch_data("" \ "SELECT id, ST_X(geom) as lon, ST_Y(geom) as lat, tags, crossing_street_name " \ "FROM pedestrian_crossings WHERE %s;" % where_clause) t2 = time.time() for row in result: signal = self.create_poi(0, int(row['id']), row['lat'], row['lon'], self.parse_hstore_column(row['tags']), 0, 0) if row['crossing_street_name'] != None: signal['name'] += ": %s" % row['crossing_street_name'] poi_list = self.insert_into_poi_list(poi_list, signal, lat, lon) # prevent accidental queries with more than 500 results if poi_list.__len__() > 500: break # check for cancel command if Config().has_session_id_to_remove(self.session_id): Config().confirm_removement_of_session_id(self.session_id) return t3 = time.time() if self.hide_log_messages == False: print "pedestrian crossings gesamt = %.2f, dbquery = %.2f, parsing = %.2f" % ( (t3 - t1), (t2 - t1), (t3 - t2)) te = time.time() if self.hide_log_messages == False: print "gesamtzeit: %.2f; anzahl entries = %d" % ( (te - ts), poi_list.__len__()) return poi_list