def handle(self, dirname, outdir, **kw):

        def store(route):
            filename = "%s%s.%s.json" % (route['borough'], route['route_no'], route['day_of_week'])
            path = os.path.join(outdir, filename)
            if os.path.exists(path):
                import pdb;pdb.set_trace()
            out = open(path, "w")
            print >>out, dumps(route)
            out.close()

        for route in parse_schedule_dir(dirname):
            store(route)
def handle_buses(dirname):

    feed = transitfeed.Loader("mta_data/bus-gtfs.zip", memory_db=False).Load() #base data
    current_borough = None

    #capture multiple stops with different box ids
    stop_name_to_stop = {}

    last_route = None
    for route_rec in parse_schedule_dir(os.path.join(dirname, 'surface-bus'), 'stif'):
        #gtfs files are organized by borough (not bus prefix)
        if current_borough != route_rec['borough']:
            if current_borough:
                feed.Validate()
                feed.WriteGoogleTransitFeed('mta_data/bus-%s.zip' % current_borough)
                feed = transitfeed.Loader("mta_data/gtfs.zip", memory_db=False).Load()
                stop_name_to_stop = {}
            current_borough = route_rec['borough']

        if route_rec['route_name_flag'] == 'X':
            #express buses
            borough = 'X'
        else:
            borough = route_rec['borough'].title()
        name = "%s%s" % (borough, 
                           route_rec['route_no'])

        print "processing route:", name

        if last_route != name:
            _shape_by_stops_cache.clear()
            last_route = name

        long_name = route_rec["street_name"]
        if long_name.startswith(name):
            long_name = long_name[len(name):].strip()


        period = feed.GetServicePeriod(route_rec['day_of_week'].upper())

        stop_hexid_to_stop = {}
        #add all stops
        for stop_rec in route_rec['stops']:
            location = "%s at %s" % (stop_rec['street1'], stop_rec['street2'])

            location = rename_location.get(location, location)

            #check for duplicate box ids
            box_no = str(stop_rec['box_no'])
            stop_id = stop_rec['stop_id']
            if location in stop_name_to_stop:
                stop_hexid_to_stop[stop_id] = stop_name_to_stop[location]
                continue

            lat = stop_rec['latitude'] / 1000000.0
            lng = stop_rec['longitude'] / 1000000.0

            #special case for QVDEP:
            if location == 'Queens Village Depot':
                lat, lng = 40.726711, -73.734779

            #not in NYC area
            if not (-72 > lng > -75) or not (41 > lat > 39):
                print "bad lat, lng", lat, lng
                import pdb;pdb.set_trace()

            #now, try to find a nearby stop
            nearest = feed.GetNearestStops(lat, lng, 1)
            if len(nearest) and not ' LANE ' in nearest[0].stop_name:
                #sometimes bus stops really are like 1 m away because 
                #they are two lanes in a multilane terminal area
                nearest = nearest[0]
            else:
                nearest = None

            if nearest and abs(nearest.stop_lat - lat) + abs(nearest.stop_lon - lng) < 0.000001:
                stop_hexid_to_stop[stop_id] = nearest
                stop_name_to_stop[location] = nearest
            else:
                stop = transitfeed.Stop(
                        lng=lng,
                        lat=lat,
                        stop_id=box_no,
                        name=location
                        )
                stop_hexid_to_stop[stop_id] = stop
                stop_name_to_stop[location] = stop

        #figure out headsigns

        headsigns = dict((sign['headsign_id'], sign['headsign']) for sign in route_rec['headsigns'])

        #get possible shapes
        names = set()
        if name in extra_names:
            extra = extra_names[name]
            if isinstance(extra, str):
                names.add(extra)
            else:
                names.update(extra)

        for trip_rec in route_rec['trips']:
            route_name = trip_rec['route_name']
            names.add(route_name)

        nameq = models.Q(route = name)
        for rname in names:
            rname = fix_leading_zeros.get(rname, rname)
            nameq |= models.Q(route__iexact = rname)

            if rname in extra_names:
                extra = extra_names[rname] 
                if isinstance(extra, str):
                    if extra not in names:
                        nameq |= models.Q(route__iexact = extra_names[rname])
                else:
                    for rname in extra:
                        if rname not in names:
                            nameq |= models.Q(route__iexact = extra_names[rname])
        shapes = list(MTABusRoute.objects.filter(nameq))

        shapes_by_direction = {}
        for shape in shapes:
            if not shape.rt_dir in shapes_by_direction:
                shapes_by_direction[shape.rt_dir] = []
            shapes_by_direction[shape.rt_dir].append(shape)
        del shapes

        #now trips
        for trip_rec in route_rec['trips']:
            if trip_rec['trip_type'] > 1:
                #these are trips to/from the depot
                continue
            if trip_rec['UNKNOWN_1'].startswith('-'):
                #these trips are bogus -- their stops are out-of-order.
                continue
            hid = trip_rec['headsign_id']
            headsign = headsigns.get(hid, long_name)

            route = route_for_trip(feed, trip_rec, headsign)

            trip = route.AddTrip(feed, headsign, service_period=period)
            stops = []
            for tripstop_rec in trip_rec['stops']:
                stop_id = tripstop_rec['stop_id']
                stop_time = google_time_from_centiminutes(tripstop_rec['minutes'])
                stop = stop_hexid_to_stop[stop_id]
                if not stop.stop_id in feed.stops:
                    feed.AddStopObject(stop)
                trip.AddStopTime(stop,
                                 stop_time=stop_time)
                stops.append(stop)

            #find the appropriate shape from the shapefiles
            trip_route_name = rename_routes.get(trip_rec['route_name'], trip_rec['route_name'])
            direction = trip_rec['direction']
            if trip_route_name in fix_direction:
                direction = fix_direction[trip_route_name].get(direction, direction)
            shapes = shapes_by_direction.get(direction)

            shape = find_shape_by_stops(feed, shapes, stops, 'bus_route_table')
            if shape:
                trip.shape_id = shape.shape_id

    feed.Validate()
    feed.WriteGoogleTransitFeed('mta_data/bus-%s.zip' % current_borough)
def handle_subway(dirname):

    feed = transitfeed.Loader("mta_data/subway-gtfs.zip", memory_db=False).Load() #base data

    dow_num_to_service_period = {'1' : 'WD',
                                 '2' : 'SAT',
                                 '3' : 'SUN'}

    for route_rec in parse_schedule_dir(os.path.join(dirname, 'rail-subway'), 'rtif'):
        route_rec['day_of_week'] = dow_num_to_service_period[route_rec['day_of_week']]

        period = feed.GetServicePeriod(route_rec['day_of_week'])
        route_id = route_rec['line']
        try:
            route = feed.GetRoute(route_id)
        except KeyError:
            route = transitfeed.Route(route_id=route_id,
                                      short_name=route_id,
                                      route_type="Subway")
            feed.AddRouteObject(route)
            feed.AddFareRuleObject(transitfeed.FareRule("regular", route_id))


        stops_by_id = {}
        for stop in route_rec['stops']:
            stop_id = stop['location_id']
            stops_by_id[stop_id] = stop

        for trip in route_rec['subway_trips']:
            line_name = trip['line_name'][-1:] #GS -> S

            if not line_name:
                continue # a bogus trip

            if line_name == '2':
                if 'NOSTRAND AVE.' in [stops_by_id[stop['stop_id']]['full_name'] for stop in trip['stops']]:

                    #the 2 train, as far as I can tell, does not
                    #actually run on the 3/4 track in Brooklyn.
                    continue

            direction = trip['direction']
            headsign = subway_headsign[route_id][direction] #fixme: depends on actual destination of train
            gtfs_trip = route.AddTrip(feed, headsign, service_period=period)
            for tripstop in trip['stops']:

                if tripstop['is_real_stop'] != 'S':
                    continue

                if tripstop['stop_id'] == '138':
                    #Cortland St
                    continue

                stop_id = tripstop['stop_id']
                if stop_id in feed.stops:
                    gtfs_stop = feed.GetStop(stop_id)
                else:
                    stop = stops_by_id[stop_id]

                    #first, the table
                    translated_full_name = stop['full_name']
                    #remove anything following a dot or a dash or an open paren                    
                    for endchar in ['.','-','(','  ']:
                        if endchar in translated_full_name:
                            translated_full_name = translated_full_name[:translated_full_name.index(endchar)]

                    #abbreviations
                    for long, abbreviated in abbreviations.items():
                        translated_full_name = translated_full_name.replace(long, abbreviated)


                    translated_full_name = translated_full_name.strip()
                    translated_full_name = translated_full_name.replace("  ", " ")


                    number_st_re = re.compile('^(\d+)')
                    number_st = number_st_re.match(translated_full_name)
                    is_num = False
                    if number_st:
                        translated_full_name = number_st.group(1)
                        is_num = True

                    translated_full_name = rename_subway_stops.get(stop['full_name'], translated_full_name
)
                    possible_stops = MTASubwayStop.objects.filter(routes__contains=line_name, facility__contains=translated_full_name)


                    #the A makes C stops late at night
                    if line_name in addl_lines:
                        possible_stops = list(possible_stops)

                        for addl_line in addl_lines[line_name]:
                            addl_possible_stops = MTASubwayStop.objects.filter(routes__contains=addl_line, facility__contains=translated_full_name)
                            for addl_stop in addl_possible_stops:
                                if not addl_stop in possible_stops:
                                    possible_stops.append(addl_stop)

                    #hard coded stop id
                    if stop_id in stop_id_to_gid:
                        possible_stops = MTASubwayStop.objects.filter(gid = stop_id_to_gid[stop_id])

                    if is_num:
                        #we need to make sure our search for 23rd st doesn't
                        #bring up 232nd st.
                        new_possible_stops = []
                        num_re = re.compile("(^|\D)" + translated_full_name + "($|\D)")
                        for possible_stop in possible_stops:
                            if num_re.search(possible_stop.facility):
                                new_possible_stops.append(possible_stop)
                        possible_stops = new_possible_stops


                    if len(possible_stops) == 0:
                        print "no stops for %s on the %s (translated to %s)" % (stop['full_name'], line_name, translated_full_name)
                        print "possible stops are %s" % sorted([s.facility for s in MTASubwayStop.objects.filter(routes__contains=line_name)])
                        import pdb;pdb.set_trace()
                        continue
                    elif len(possible_stops) > 1:
                        print "too many stops for %s on the %s (translated to %s): %s" % (stop['full_name'], line_name, translated_full_name, [(s.facility, s.gid, s.routes) for s in possible_stops])
                        import pdb;pdb.set_trace()
                        continue
                    else:
                        dbstop = possible_stops[0]

                    gtfs_stop = transitfeed.Stop(
                        lng=dbstop.the_geom.x,
                        lat=dbstop.the_geom.y,
                        stop_id=stop_id,
                        name=dbstop.facility
                        )
                    feed.AddStopObject(gtfs_stop)            

                stop_time = google_time_from_centiminutes(tripstop['stop_time'])
                gtfs_trip.AddStopTime(gtfs_stop, stop_time=stop_time)

    feed.WriteGoogleTransitFeed('mta_data/subway.zip')
Beispiel #4
0
def handle_subway(dirname):

    feed = transitfeed.Loader("mta_data/subway-gtfs.zip", memory_db=False).Load() #base data

    dow_num_to_service_period = {'1' : 'WD',
                                 '2' : 'SAT',
                                 '3' : 'SUN'}

    for route_rec in parse_schedule_dir(os.path.join(dirname, 'rail-subway'), 'rtif'):
        route_rec['day_of_week'] = dow_num_to_service_period[route_rec['day_of_week']]

        period = feed.GetServicePeriod(route_rec['day_of_week'])
        route_id = route_rec['line']
        try:
            route = feed.GetRoute(route_id)
        except KeyError:
            route = transitfeed.Route(route_id=route_id,
                                      short_name=route_id,
                                      route_type="Subway")
            feed.AddRouteObject(route)
            feed.AddFareRuleObject(transitfeed.FareRule("regular", route_id))


        stops_by_id = {}
        for stop in route_rec['stops']:
            stop_id = stop['location_id']
            stops_by_id[stop_id] = stop

        for trip in route_rec['subway_trips']:
            line_name = trip['line_name'][-1:] #GS -> S

            if not line_name:
                continue # a bogus trip

            if line_name == '2':
                if 'NOSTRAND AVE.' in [stops_by_id[stop['stop_id']]['full_name'] for stop in trip['stops']]:

                    #the 2 train, as far as I can tell, does not
                    #actually run on the 3/4 track in Brooklyn.
                    continue

            direction = trip['direction']
            headsign = subway_headsign[route_id][direction] #fixme: depends on actual destination of train
            gtfs_trip = route.AddTrip(feed, headsign, service_period=period)
            for tripstop in trip['stops']:

                if tripstop['is_real_stop'] != 'S':
                    continue

                if tripstop['stop_id'] == '138':
                    #Cortland St
                    continue

                direction = trip['direction']

                stop_id = tripstop['stop_id']
                dir_stop_id = stop_id + "_" + direction
                if dir_stop_id in feed.stops:
                    gtfs_stop = feed.GetStop(dir_stop_id)
                elif stop_id in feed.stops:
                    gtfs_stop = feed.GetStop(stop_id)
                else:
                    dbstop = MTASubwayStop.objects.filter(gid=stop_id_to_gid[stop_id])[0]
                    if stop_id in end_of_line:
                        gtfs_stop = transitfeed.Stop(
                            lng=dbstop.the_geom.x,
                            lat=dbstop.the_geom.y,
                            stop_id=stop_id,
                            name=dbstop.facility
                            )
                        feed.AddStopObject(gtfs_stop)
                    else:
                        for new_direction in 'NS':                        
                            new_gtfs_stop = transitfeed.Stop(
                                lng=dbstop.the_geom.x,
                                lat=dbstop.the_geom.y,
                                stop_id=stop_id + "_" + new_direction,
                                name=dbstop.facility
                                )
                        feed.AddStopObject(new_gtfs_stop)
                        if new_direction == direction:
                            gtfs_stop = new_gtfs_stop
                
                stop_time = google_time_from_centiminutes(tripstop['stop_time'])
                gtfs_trip.AddStopTime(gtfs_stop, stop_time=stop_time)

    feed.WriteGoogleTransitFeed('mta_data/subway.zip')
    #add back extra files
    z = zipfile.ZipFile('mta_data/subway.zip', 'a', zipfile.ZIP_DEFLATED)
    z.write('mta_data/subway-gtfs/entrances.txt', 'entrances.txt')
    z.write('mta_data/subway-gtfs/stop_entrances.txt', 'stop_entrances.txt')
    z.close()