Beispiel #1
0
class Fare(Base):
    """A fare class"""

    feed = models.ForeignKey('Feed')
    fare_id = models.CharField(max_length=255,
                               db_index=True,
                               help_text="Unique identifier for a fare class")
    price = models.DecimalField(
        max_digits=17,
        decimal_places=4,
        help_text="Fare price, in units specified by currency_type")
    currency_type = models.CharField(
        max_length=3, help_text="ISO 4217 alphabetical currency code")
    payment_method = models.IntegerField(
        default=1,
        choices=((0, 'Fare is paid on board.'),
                 (1, 'Fare must be paid before boarding.')),
        help_text="When is the fare paid?")
    transfers = models.IntegerField(
        default=None,
        null=True,
        blank=True,
        choices=((0, 'No transfers permitted on this fare.'),
                 (1, 'Passenger may transfer once.'),
                 (2, 'Passenger may transfer twice.'),
                 (None, 'Unlimited transfers are permitted.')),
        help_text="Are transfers permitted?")
    transfer_duration = models.IntegerField(
        null=True,
        blank=True,
        help_text="Time in seconds until a ticket or transfer expires")
    extra_data = JSONField(default={}, blank=True, null=True)

    def __str__(self):
        return u"%d-%s(%s %s)" % (self.feed.id, self.fare_id, self.price,
                                  self.currency_type)

    class Meta:
        db_table = 'fare'
        app_label = 'multigtfs'

    # For Base import/export
    _column_map = (('fare_id', 'fare_id'), ('price', 'price'),
                   ('currency_type', 'currency_type'), ('payment_method',
                                                        'payment_method'),
                   ('transfers', 'transfers'), ('transfer_duration',
                                                'transfer_duration'))
    _filename = 'fare_attributes.txt'
    _unique_fields = ('fare_id', )
Beispiel #2
0
class Frequency(Base):
    """Description of a trip that repeats without fixed stop times"""
    trip = models.ForeignKey('Trip')
    start_time = SecondsField(
        help_text="Time that the service begins at the specified frequency")
    end_time = SecondsField(
        help_text="Time that the service ends at the specified frequency")
    headway_secs = models.IntegerField(
        help_text="Time in seconds before returning to same stop")
    exact_times = models.CharField(
        max_length=1,
        blank=True,
        choices=((0, 'Trips are not exactly scheduled'),
                 (1, 'Trips are exactly scheduled from start time')),
        help_text="Should frequency-based trips be exactly scheduled?")
    extra_data = JSONField(default={}, blank=True, null=True)

    def __str__(self):
        return str(self.trip)

    class Meta:
        db_table = 'frequency'
        app_label = 'multigtfs'
        verbose_name_plural = "frequencies"

    # For Base import/export
    _column_map = (('trip_id', 'trip__trip_id'), ('start_time', 'start_time'),
                   ('end_time', 'end_time'), ('headway_secs', 'headway_secs'),
                   ('exact_times', 'exact_times'))
    _filename = 'frequencies.txt'
    _rel_to_feed = 'trip__route__feed'
    _unique_fields = ('trip_id', 'start_time')
class ServiceDate(Base):
    """Dates that a route is active."""

    service = models.ForeignKey('Service')
    date = models.DateField(
        help_text="Date that the service differs from the norm.")
    exception_type = models.IntegerField(
        default=1,
        choices=((1, 'Added'), (2, 'Removed')),
        help_text="Is service added or removed on this date?")
    extra_data = JSONField(default={}, blank=True, null=True)

    def __str__(self):
        return ("%d-%s %s %s" %
                (self.service.feed.id, self.service.service_id, self.date,
                 'Added' if self.exception_type == 1 else 'Removed'))

    class Meta:
        db_table = 'service_date'
        app_label = 'multigtfs'

    # For Base import/export
    _column_map = (('service_id', 'service__service_id'), ('date', 'date'),
                   ('exception_type', 'exception_type'))
    _filename = 'calendar_dates.txt'
    _rel_to_feed = 'service__feed'
    _sort_order = ('date', 'exception_type')
    _unique_fields = ('service_id', 'date')
Beispiel #4
0
class StopTime(Base):
    """A specific stop on a route on a trip.

    This implements stop_times.txt in the GTFS feed
    """
    trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
    stop = models.ForeignKey(Stop, on_delete=models.CASCADE)
    arrival_time = SecondsField(
        default=None, null=True, blank=True,
        help_text="Arrival time. Must be set for end stops of trip.")
    departure_time = SecondsField(
        default=None, null=True, blank=True,
        help_text='Departure time. Must be set for end stops of trip.')
    stop_sequence = models.IntegerField()
    stop_headsign = models.CharField(
        max_length=255, blank=True,
        help_text="Sign text that identifies the stop for passengers")
    pickup_type = models.CharField(
        max_length=1, blank=True,
        choices=(('0', 'Regularly scheduled pickup'),
                 ('1', 'No pickup available'),
                 ('2', 'Must phone agency to arrange pickup'),
                 ('3', 'Must coordinate with driver to arrange pickup')),
        help_text="How passengers are picked up")
    drop_off_type = models.CharField(
        max_length=1, blank=True,
        choices=(('0', 'Regularly scheduled drop off'),
                 ('1', 'No drop off available'),
                 ('2', 'Must phone agency to arrange drop off'),
                 ('3', 'Must coordinate with driver to arrange drop off')),
        help_text="How passengers are picked up")
    shape_dist_traveled = models.FloatField(
        "shape distance traveled",
        null=True, blank=True,
        help_text='Distance of stop from start of shape')
    extra_data = JSONField(default={}, blank=True, null=True)

    def __str__(self):
        return "%s-%s-%s" % (self.trip, self.stop.stop_id, self.stop_sequence)

    class Meta:
        db_table = 'stop_time'
        app_label = 'multigtfs'

    _column_map = (
        ('trip_id', 'trip__trip_id'),
        ('arrival_time', 'arrival_time'),
        ('departure_time', 'departure_time'),
        ('stop_id', 'stop__stop_id'),
        ('stop_sequence', 'stop_sequence'),
        ('stop_headsign', 'stop_headsign'),
        ('pickup_type', 'pickup_type'),
        ('drop_off_type', 'drop_off_type'),
        ('shape_dist_traveled', 'shape_dist_traveled')
    )
    _filename = 'stop_times.txt'
    _rel_to_feed = 'trip__route__feed'
    _sort_order = ('trip__trip_id', 'stop_sequence')
    _unique_fields = ('trip_id', 'stop_sequence')
Beispiel #5
0
class ShapePoint(Base):
    """A point along the shape"""
    shape = models.ForeignKey('Shape', related_name='points')
    point = models.PointField(
        geography=MULTIGTFS_USE_GEOGRAPHY, srid=MULTIGTFS_SRID,
        help_text='WGS 84 latitude/longitude of shape point')
    sequence = models.IntegerField()
    traveled = models.FloatField(
        null=True, blank=True,
        help_text='Distance of point from start of shape')

    def __unicode__(self):
        return u"%s-%d" % (self.shape, self.sequence)

    def getlon(self):
        return self.point[0] if self.point else 0.0

    def setlon(self, value):
        if self.point:
            self.point[0] = value
        else:
            self.point = "POINT(%s 0)" % value

    lon = property(getlon, setlon, doc="WGS 84 longitude of shape point")

    def getlat(self):
        return self.point[1] if self.point else 0.0

    def setlat(self, value):
        if self.point:
            self.point[1] = value
        else:
            self.point = "POINT(0 %s)" % value

    lat = property(getlat, setlat, doc="WGS 84 latitude of shape point")

    def __init__(self, *args, **kwargs):
        lat = kwargs.pop('lat', None)
        lon = kwargs.pop('lon', None)
        if lat is not None or lon is not None:
            assert kwargs.get('point') is None
            msg = "Setting ShapePoint location with lat and lon is deprecated"
            warnings.warn(msg, DeprecationWarning)
            kwargs['point'] = "POINT(%s %s)" % (lon or 0.0, lat or 0.0)
        super(ShapePoint, self).__init__(*args, **kwargs)

    class Meta:
        db_table = 'shape_point'
        app_label = 'multigtfs'

    _column_map = (
        ('shape_id', 'shape__shape_id'),
        ('shape_pt_lat', 'point[1]'),
        ('shape_pt_lon', 'point[0]'),
        ('shape_pt_sequence', 'sequence'),
        ('shape_dist_traveled', 'traveled')
    )
    _rel_to_feed = 'shape__feed'
    _sort_order = ('shape__shape_id', 'sequence')
Beispiel #6
0
class Transfer(Base):
    """Create additional rules for transfers between ambiguous stops.

    Implements transfer.txt in the GTFS feed.
    """
    from_stop = models.ForeignKey(
        'Stop',
        on_delete=models.CASCADE,
        related_name='transfer_from_stop',
        help_text='Stop where a connection between routes begins.')
    to_stop = models.ForeignKey(
        'Stop',
        on_delete=models.CASCADE,
        related_name='transfer_to_stop',
        help_text='Stop where a connection between routes ends.')
    transfer_type = models.IntegerField(
        default=0,
        blank=True,
        choices=((0, 'Recommended transfer point'),
                 (1, 'Timed transfer point (vehicle will wait)'),
                 (2, 'min_transfer_time needed to successfully transfer'),
                 (3, 'No transfers possible')),
        help_text="What kind of transfer?")
    min_transfer_time = models.IntegerField(
        null=True,
        blank=True,
        help_text="How many seconds are required to transfer?")
    extra_data = JSONField(default={}, blank=True, null=True)

    def __str__(self):
        return "%s-%s" % (self.from_stop, self.to_stop.stop_id)

    class Meta:
        db_table = 'transfer'
        app_label = 'multigtfs'

    _column_map = (('from_stop_id',
                    'from_stop__stop_id'), ('to_stop_id', 'to_stop__stop_id'),
                   ('transfer_type', 'transfer_type'), ('min_transfer_time',
                                                        'min_transfer_time'))
    _filename = 'transfers.txt'
    _rel_to_feed = 'from_stop__feed'
    _sort_order = ('from_stop__stop_id', 'to_stop__stop_id')
    _unique_fields = ('from_stop_id', 'to_stop_id')
Beispiel #7
0
class Route(Base):
    """A transit route"""

    feed = models.ForeignKey('Feed')
    route_id = models.CharField(
        max_length=255, db_index=True,
        help_text="Unique identifier for route.")
    agency = models.ForeignKey(
        'Agency', null=True, blank=True, help_text="Agency for this route.")
    short_name = models.CharField(
        max_length=10,
        help_text="Short name of the route")
    long_name = models.CharField(
        max_length=255,
        help_text="Long name of the route")
    desc = models.TextField(
        blank=True,
        help_text="Long description of a route")
    rtype = models.IntegerField(
        choices=((0, 'Tram, Streetcar, or Light rail'),
                 (1, 'Subway or Metro'),
                 (2, 'Rail'),
                 (3, 'Bus'),
                 (4, 'Ferry'),
                 (5, 'Cable car'),
                 (6, 'Gondola or Suspended cable car'),
                 (7, 'Funicular')),
        help_text='Type of transportation used on route')
    url = models.URLField(
        blank=True, help_text="Web page about for the route")
    color = models.CharField(
        max_length=6, blank=True,
        help_text="Color of route in hex")
    text_color = models.CharField(
        max_length=6, blank=True,
        help_text="Color of route text in hex")

    def __unicode__(self):
        return u"%d-%s" % (self.feed.id, self.route_id)

    class Meta:
        db_table = 'route'
        app_label = 'multigtfs'

    _column_map = (
        ('route_id', 'route_id'),
        ('agency_id', 'agency__agency_id'),
        ('route_short_name', 'short_name'),
        ('route_long_name', 'long_name'),
        ('route_desc', 'desc'),
        ('route_type', 'rtype'),
        ('route_url', 'url'),
        ('route_color', 'color'),
        ('route_text_color', 'text_color')
    )
    _sort_order = ('route_id', 'short_name')
Beispiel #8
0
class Route(Base):
    """A transit route"""

    feed = models.ForeignKey('Feed')
    route_id = models.CharField(max_length=255,
                                db_index=True,
                                help_text="Unique identifier for route.")
    agency = models.ForeignKey('Agency',
                               null=True,
                               blank=True,
                               help_text="Agency for this route.")
    short_name = models.CharField(max_length=63,
                                  help_text="Short name of the route")
    long_name = models.CharField(max_length=255,
                                 help_text="Long name of the route")
    desc = models.TextField(blank=True,
                            help_text="Long description of a route")
    rtype = models.IntegerField(
        choices=((0, 'Tram, Streetcar, or Light rail'), (1, 'Subway or Metro'),
                 (2, 'Rail'), (3, 'Bus'), (4, 'Ferry'), (5, 'Cable car'),
                 (6, 'Gondola or Suspended cable car'), (7, 'Funicular')),
        help_text='Type of transportation used on route')
    url = models.URLField(blank=True, help_text="Web page about for the route")
    color = models.CharField(max_length=6,
                             blank=True,
                             help_text="Color of route in hex")
    text_color = models.CharField(max_length=6,
                                  blank=True,
                                  help_text="Color of route text in hex")
    geometry = models.MultiLineStringField(null=True,
                                           blank=True,
                                           help_text='Geometry cache of Trips')

    def update_geometry(self):
        """Update the geometry from the Trips"""
        original = self.geometry
        trips = self.trip_set.exclude(geometry=None)
        unique_coords = set()
        unique_geom = list()
        for t in trips:
            coords = t.geometry.coords
            if coords not in unique_coords:
                unique_coords.add(coords)
                unique_geom.append(t.geometry)
        self.geometry = MultiLineString(unique_geom)
        if self.geometry != original:
            self.save()

    def __unicode__(self):
        return u"%d-%s" % (self.feed.id, self.route_id)

    def stop_set(self):
        stoptimes = itertools.chain(*[
            trip.stoptime_set.all().distinct('stop')
            for trip in self.trip_set.all()
        ])
        return set([stoptime.stop for stoptime in stoptimes])

    class Meta:
        db_table = 'multigtfs_route'
        app_label = 'multigtfs'

    _column_map = (('route_id', 'route_id'),
                   ('agency_id', 'agency__agency_id'), ('route_short_name',
                                                        'short_name'),
                   ('route_long_name', 'long_name'), ('route_desc', 'desc'),
                   ('route_type', 'rtype'), ('route_url', 'url'),
                   ('route_color', 'color'), ('route_text_color',
                                              'text_color'))
    _sort_order = ('route_id', 'short_name')
Beispiel #9
0
class ShapePoint(Base):
    """A point along the shape"""
    shape = models.ForeignKey(
        'Shape', on_delete=models.CASCADE, related_name='points')
    point = models.PointField(
        help_text='WGS 84 latitude/longitude of shape point')
    sequence = models.IntegerField()
    traveled = models.FloatField(
        null=True, blank=True,
        help_text='Distance of point from start of shape')
    extra_data = JSONField(default={}, blank=True, null=True)

    def __str__(self):
        return "%s-%d" % (self.shape, self.sequence)

    def getlon(self):
        return self.point[0] if self.point else 0.0

    def setlon(self, value):
        if self.point:
            self.point[0] = value
        else:
            self.point = "POINT(%s 0)" % value

    lon = property(getlon, setlon, doc="WGS 84 longitude of shape point")

    def getlat(self):
        return self.point[1] if self.point else 0.0

    def setlat(self, value):
        if self.point:
            self.point[1] = value
        else:
            self.point = "POINT(0 %s)" % value

    lat = property(getlat, setlat, doc="WGS 84 latitude of shape point")

    def __init__(self, *args, **kwargs):
        """Initialize a ShapePoint

        If the legacy lat and lon params are used, then warn and initialize
        the point from them.
        """
        lat = kwargs.pop('lat', None)
        lon = kwargs.pop('lon', None)
        if lat is not None or lon is not None:
            assert kwargs.get('point') is None
            msg = "Setting ShapePoint location with lat and lon is deprecated"
            warnings.warn(msg, DeprecationWarning)
            kwargs['point'] = "POINT(%s %s)" % (lon or 0.0, lat or 0.0)

        super(ShapePoint, self).__init__(*args, **kwargs)

    class Meta:
        db_table = 'shape_point'
        app_label = 'multigtfs'

    _column_map = (
        ('shape_id', 'shape__shape_id'),
        ('shape_pt_lat', 'point[1]'),
        ('shape_pt_lon', 'point[0]'),
        ('shape_pt_sequence', 'sequence'),
        ('shape_dist_traveled', 'traveled')
    )
    _filename = 'shapes.txt'
    _rel_to_feed = 'shape__feed'
    _sort_order = ('shape__shape_id', 'sequence')
    _unique_fields = ('shape_id', 'shape_pt_sequence')
class Route(Base):
    """A transit route

    Maps to route.txt in the GTFS feed.
    """

    feed = models.ForeignKey('Feed', on_delete=models.CASCADE)
    route_id = models.CharField(max_length=255,
                                db_index=True,
                                help_text="Unique identifier for route.")
    agency = models.ForeignKey('Agency',
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL,
                               help_text="Agency for this route.")
    short_name = models.CharField(max_length=63,
                                  help_text="Short name of the route")
    long_name = models.CharField(max_length=255,
                                 help_text="Long name of the route")
    desc = models.TextField("description",
                            blank=True,
                            help_text="Long description of a route")
    rtype = models.IntegerField(
        "route type",
        choices=((0, 'Tram, Streetcar, or Light rail'), (1, 'Subway or Metro'),
                 (2, 'Rail'), (3, 'Bus'), (4, 'Ferry'), (5, 'Cable car'),
                 (6, 'Gondola or Suspended cable car'), (7, 'Funicular')),
        help_text='Type of transportation used on route')
    url = models.URLField(blank=True, help_text="Web page about for the route")
    color = models.CharField(max_length=6,
                             blank=True,
                             help_text="Color of route in hex")
    text_color = models.CharField(max_length=6,
                                  blank=True,
                                  help_text="Color of route text in hex")
    geometry = models.MultiLineStringField(null=True,
                                           blank=True,
                                           help_text='Geometry cache of Trips')
    extra_data = JSONField(default={}, blank=True, null=True)

    def update_geometry(self):
        """Update the geometry from the Trips"""
        original = self.geometry
        trips = self.trip_set.exclude(geometry__isnull=True)
        unique_coords = set()
        unique_geom = list()
        for t in trips:
            coords = t.geometry.coords
            if coords not in unique_coords:
                unique_coords.add(coords)
                unique_geom.append(t.geometry)
        self.geometry = MultiLineString(unique_geom)
        if self.geometry != original:
            self.save()

    def __str__(self):
        return "%d-%s" % (self.feed.id, self.route_id)

    class Meta:
        db_table = 'route'
        app_label = 'multigtfs'

    _column_map = (('route_id', 'route_id'),
                   ('agency_id', 'agency__agency_id'), ('route_short_name',
                                                        'short_name'),
                   ('route_long_name', 'long_name'), ('route_desc', 'desc'),
                   ('route_type', 'rtype'), ('route_url', 'url'),
                   ('route_color', 'color'), ('route_text_color',
                                              'text_color'))
    _filename = 'routes.txt'
    _sort_order = ('route_id', 'short_name')
    _unique_fields = ('route_id', )