示例#1
0
def classify_locations_by_intersection(conn):
    curs = conn.cursor()
    curs.execute("""select latitude, longitude, time, intersection from
    location where bus_id = 234105 order by time""")

    intersections = []
    locations = []

    for result in curs.fetchall():
        latitude, longitude, time, intersection = result
        location = (latitude, longitude)
        point = dict(latitude=latitude,
                     longitude=longitude,
                     distance=st_line_locate_point(route, location),
                     time=time)
        if intersection:
            intersections.append(point)
        else:
            locations.append(point)

    prev_intersection = intersections[0]
    next_intersection = intersections[1]
    i = 1
    rejected = 0
    accepted = 0
    start_time = locations[0]['time']
    for point in locations:
        if point['time'] < prev_intersection['time']:
            continue #silently reject because it is temporally before the bus starts
        while point['time'] > next_intersection['time']:
            #advance intersections to match time
            prev_intersection = next_intersection
            i += 1
            if i < len(intersections):
                next_intersection = intersections[i]
                break
        #check distance against intersection distances

        if prev_intersection['distance'] <= point['distance'] <= next_intersection['distance']:
            accepted += 1
            style = "accepted"
        else:
            rejected += 1
            style = "rejected"

        print """
                <Placemark>
        <name>%s - %s</name>
        <styleUrl>#%s</styleUrl>
        <Point>
            <coordinates>
                %s, %s
            </coordinates>
        </Point>

    </Placemark>
""" % (point['time'] - start_time, style, style, point['longitude'], point['latitude'])

    print "</Document></kml>"
    print >>sys.stderr, "accepted, rejected, total", accepted, rejected, len(locations)
def find_shape_by_stops(feed, candidate_routes, stops, table_name):
    """This is brutal -- it matches a set of route paths against a
    known set of bus stops to choose the route path which falls
    nearest to the trip."""

    key = freeze([candidate_routes, stops, table_name])
    if key in _shape_by_stops_cache:
        return _shape_by_stops_cache[key]

    best_route = None
    best_dist = 100000000000000

    #routes are sorted by length, because we want to use the shortest
    #route that matches the points.
    for route in sorted(candidate_routes, key=lambda route:route.the_geom.length):
        total_dist = 0
        for stop in stops:
            total_dist += route.the_geom.distance(Point(stop.stop_lon, stop.stop_lat))
        if total_dist < best_dist:
            best_dist = total_dist
            best_route = route

    if candidate_routes[0].route == 'S55':
        print "The MTA's route shape for S55 is from 2007.  So we're skipping it."
        return None

    if candidate_routes[0].route == 'Q48':
        #this is a total hack; the Q48 is in general a total hack
        if len(stops) == 22:
            for route in candidate_routes:
                if route.gid == 10707:
                    best_route = route


    #figure out if the set of stops is shorter than the best route
    #(the bus stops or ends in the middle of the route) and if so,
    #cut the route down.

    start_location = st_line_locate_point(best_route.the_geom, (stops[0].stop_lon, stops[0].stop_lat))

    end_location = st_line_locate_point(best_route.the_geom, (stops[-1].stop_lon, stops[-1].stop_lat))

    if start_location > end_location:
        print "Backwards route %s, Skipping." % route.gid
        return None

    if end_location - start_location < 0.98 and best_route.route not in loop_routes:
        if end_location - start_location < 0.05:
            print """"This is a very short route segment. Is it a 
miscategorized loop?  Route: %s, first and last: %s, %s""" % (
                best_route.route, stops[0].location, stops[-1].location)
        #create a new shape for the short route
        i = 0
        while 1:
            new_gid = str(best_route.gid * 100 + 20000 + i)
            i += 1
            try:
                feed.GetShape(new_gid)
            except KeyError:
                break

        shape = transitfeed.Shape(new_gid)

        #while a binary search for start and end would probably be
        #faster, it assumes that the shapes are correctly plotted in
        #ascending order, which they appear not to be.

        distance = 0
        for point in best_route.the_geom.coords:
            last_distance = distance
            distance = st_line_locate_point(best_route.the_geom, point)
            if start_location <= distance - 0.001:
                if distance <= end_location + 0.001:
                    shape.AddPoint(point[1], point[0])
                else:
                    line_distance_span = distance - last_distance;
                    end_distance_span = end_location - last_distance;
                    interp_ratio = end_distance_span / line_distance_span
                    interp_x = last_point[1] * interp_ratio + point[1] * (1 - interp_ratio)
                    interp_y = last_point[0] * interp_ratio + point[0] * (1 - interp_ratio)
                    shape.AddPoint(interp_x, interp_y)
                    
            last_point = point

        feed.AddShapeObject(shape)
    else: #not a too-short route
        try:
            shape = feed.GetShape(str(best_route.gid))
        except KeyError:
            shape = transitfeed.Shape(str(best_route.gid))
            for point in best_route.the_geom.coords:
                shape.AddPoint(point[1], point[0])

            feed.AddShapeObject(shape)

    _shape_by_stops_cache[key] = shape
    return shape