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')
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 Stop(Base): """A stop or station""" feed = models.ForeignKey('Feed') stop_id = models.CharField( max_length=255, db_index=True, help_text="Unique identifier for a stop or station.") code = models.CharField( max_length=255, blank=True, help_text="Uniquer identifier (short text or number) for passengers.") name = models.CharField(max_length=255, help_text="Name of stop in local vernacular.") desc = models.CharField("description", max_length=255, blank=True, help_text='Description of a stop.') point = models.PointField( help_text='WGS 84 latitude/longitude of stop or station') zone = models.ForeignKey('Zone', null=True, blank=True, help_text="Fare zone for a stop ID.") url = models.URLField(blank=True, help_text="URL for the stop") location_type = models.CharField(max_length=1, blank=True, choices=(('0', 'Stop'), ('1', 'Station')), help_text="Is this a stop or station?") parent_station = models.ForeignKey( 'Stop', null=True, blank=True, help_text="The station associated with the stop") timezone = models.CharField(max_length=255, blank=True, help_text="Timezone of the stop") wheelchair_boarding = models.CharField( max_length=1, blank=True, choices=(('0', 'No information'), ('1', 'Some wheelchair boarding'), ('2', 'No wheelchair boarding')), help_text='Is wheelchair boarding possible?') extra_data = JSONField(default={}, blank=True, null=True) def __str__(self): return "%d-%s" % (self.feed_id, self.stop_id) 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 stop or station") 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 stop or station") 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 Stop 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(Stop, self).__init__(*args, **kwargs) class Meta: db_table = 'stop' app_label = 'multigtfs' _column_map = ( ('stop_id', 'stop_id'), ('stop_code', 'code'), ('stop_name', 'name'), ('stop_desc', 'desc'), ('stop_lat', 'point[1]'), ('stop_lon', 'point[0]'), ('zone_id', 'zone__zone_id'), ('stop_url', 'url'), ('location_type', 'location_type'), ('parent_station', 'parent_station__stop_id'), ('stop_timezone', 'timezone'), ('wheelchair_boarding', 'wheelchair_boarding'), ) _filename = 'stops.txt' _unique_fields = ('stop_id', ) @classmethod def import_txt(cls, txt_file, feed): '''Import from a stops.txt file Stations need to be imported before stops ''' txt = txt_file.read() def is_station(pairs): '''Does the row represent a station?''' for name, val in pairs: if name == 'location_type': return val == '1' return False logger.info("Importing station stops") stations = super(Stop, cls).import_txt(StringIO(txt), feed, is_station) logger.info("Imported %d station stops", stations) def is_stop(pairs): '''Does the row represent a stop?''' for name, val in pairs: if name == 'location_type': return val != '1' return True logger.info("Importing non-station stops") stops = super(Stop, cls).import_txt(StringIO(txt), feed, is_stop) logger.info("Imported %d non-station stops", stops) return stations + stops
class Stop(Base): """A stop or station""" feed = models.ForeignKey('Feed') stop_id = models.CharField( max_length=255, db_index=True, help_text="Unique identifier for a stop or station.") code = models.CharField( max_length=255, blank=True, help_text="Uniquer identifier (short text or number) for passengers.") name = models.CharField(max_length=255, help_text="Name of stop in local vernacular.") desc = models.CharField(max_length=255, blank=True, help_text='Description of a stop.') point = models.PointField( geography=MULTIGTFS_USE_GEOGRAPHY, srid=MULTIGTFS_SRID, help_text='WGS 84 latitude/longitude of stop or station') zone = models.ForeignKey('Zone', null=True, blank=True, help_text="Fare zone for a stop ID.") url = models.URLField(blank=True, help_text="URL for the stop") location_type = models.CharField(max_length=1, blank=True, choices=(('0', 'Stop'), ('1', 'Station')), help_text="Is this a stop or station?") parent_station = models.ForeignKey( 'Stop', null=True, blank=True, help_text="The station associated with the stop") timezone = models.CharField(max_length=255, blank=True, help_text="Timezone of the stop") wheelchair_boarding = models.CharField( max_length=1, blank=True, choices=(('0', '0'), ('1', '1'), ('2', '2')), help_text= "Whether wheelchair boardings are possible from the specified stop or station" ) def __unicode__(self): return u"%d-%s" % (self.feed.id, self.stop_id) 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 stop or station") 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 stop or station") 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 Stop 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(Stop, self).__init__(*args, **kwargs) class Meta: db_table = 'stop' app_label = 'multigtfs' _column_map = (('stop_id', 'stop_id'), ('stop_code', 'code'), ('stop_name', 'name'), ('stop_desc', 'desc'), ('stop_lat', 'point[1]'), ('stop_lon', 'point[0]'), ('zone_id', 'zone__zone_id'), ('stop_url', 'url'), ('location_type', 'location_type'), ('parent_station', 'parent_station__stop_id'), ('stop_timezone', 'timezone'), ('wheelchair_boarding', 'wheelchair_boarding')) @classmethod def import_txt(cls, txt_file, feed): '''Import from a stops.txt file Stations need to be imported before stops ''' def writeheader(writer): ''' Write the header row for a DictWriter CSV file This is a member function of DictWriter in Python 2.7 ''' writer.writerow(dict((fn, fn) for fn in writer.fieldnames)) txt = txt_file.read() fieldnames, _ = zip(*cls._column_map) has_stations = False stations_csv = StringIO.StringIO() stations = DictWriter(stations_csv, fieldnames) has_stops = False stops_csv = StringIO.StringIO() stops = DictWriter(stops_csv, fieldnames) for row in DictReader(StringIO.StringIO(txt)): if row.get('location_type') == '1': if not has_stations: writeheader(stations) has_stations = True stations.writerow(row) else: if not has_stops: writeheader(stops) has_stops = True stops.writerow(row) if has_stations: super(Stop, cls).import_txt(StringIO.StringIO(stations_csv.getvalue()), feed) if has_stops: super(Stop, cls).import_txt(StringIO.StringIO(stops_csv.getvalue()), feed)