예제 #1
0
 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
예제 #3
0
 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)
예제 #4
0
 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)
예제 #5
0
 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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #12
0
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')
예제 #13
0
    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
예제 #14
0
    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
예제 #15
0
    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
예제 #16
0
    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