Backend changes and sql convenience
- Added sql files to create and drop db and to feed example data. - Added bridge to import (and later export) data from a gtfs.GTFS object to the database. - Updated models and migrations to implement the whole GTFS reference.
This commit is contained in:
291
transport_accessibility/pt_map/bridge.py
Normal file
291
transport_accessibility/pt_map/bridge.py
Normal file
@@ -0,0 +1,291 @@
|
||||
import pt_map.gtfs
|
||||
import pt_map.models
|
||||
import pandas as pd
|
||||
from pattern.text.en import singularize
|
||||
import math
|
||||
import numbers
|
||||
import email.utils
|
||||
import time
|
||||
import datetime
|
||||
import django.db.models
|
||||
|
||||
gtfs_schema = {
|
||||
"agency": [
|
||||
"agency_id",
|
||||
"agency_name",
|
||||
"agency_url",
|
||||
"agency_timezone",
|
||||
"agency_lang",
|
||||
"agency_phone",
|
||||
"agency_email",
|
||||
"agency_fare_url"
|
||||
],
|
||||
"stops": [
|
||||
"stop_id",
|
||||
"stop_code",
|
||||
"stop_name",
|
||||
"stop_desc",
|
||||
"stop_lat",
|
||||
"stop_lon",
|
||||
"zone_id",
|
||||
"stop_url",
|
||||
"location_type",
|
||||
"parent_station",
|
||||
"stop_timezone",
|
||||
"wheelchair_boarding",
|
||||
"level_id",
|
||||
"platform_code"
|
||||
],
|
||||
"routes": [
|
||||
"route_id",
|
||||
"agency_id",
|
||||
"route_short_name",
|
||||
"route_long_name",
|
||||
"route_desc",
|
||||
"route_type",
|
||||
"route_url",
|
||||
"route_color",
|
||||
"route_text_color",
|
||||
"route_sort_order",
|
||||
"continuous_pickup",
|
||||
"continuous_drop_off"
|
||||
],
|
||||
"trips": [
|
||||
"trip_id",
|
||||
"route_id",
|
||||
"service_id",
|
||||
"trip_headsign",
|
||||
"trip_short_name",
|
||||
"direction_id",
|
||||
"block_id",
|
||||
"shape_id",
|
||||
"wheelchair_accessible",
|
||||
"bikes_allowed"
|
||||
],
|
||||
"stop_times": [
|
||||
"trip_id",
|
||||
"arrival_time",
|
||||
"departure_time",
|
||||
"stop_id",
|
||||
"stop_sequence",
|
||||
"stop_headsign",
|
||||
"pickup_type",
|
||||
"drop_off_type",
|
||||
"shape_dist_traveled",
|
||||
"timepoint"
|
||||
],
|
||||
"calendar": [
|
||||
"service_id",
|
||||
"monday",
|
||||
"tuesday",
|
||||
"wednesday",
|
||||
"thursday",
|
||||
"friday",
|
||||
"saturday",
|
||||
"sunday",
|
||||
"start_date",
|
||||
"end_date"
|
||||
],
|
||||
"calendar_dates": [
|
||||
"service_id",
|
||||
"date",
|
||||
"exception_type"
|
||||
],
|
||||
"fare_attributes": [
|
||||
"fare_id",
|
||||
"price",
|
||||
"currency_type",
|
||||
"payment_method",
|
||||
"transfers",
|
||||
"transfer_duration"
|
||||
],
|
||||
"fare_rules": [
|
||||
"fare_id",
|
||||
"route_id",
|
||||
"origin_id",
|
||||
"destination_id",
|
||||
"contains_id"
|
||||
],
|
||||
"timeframes": [
|
||||
"timeframe_id",
|
||||
"start_time",
|
||||
"end_time",
|
||||
"headway_sec",
|
||||
"exact_times"
|
||||
],
|
||||
"fare_media": [
|
||||
"media_id",
|
||||
"agency_id",
|
||||
"fare_id",
|
||||
"seat_type",
|
||||
"price"
|
||||
],
|
||||
"fare_products": [
|
||||
"product_id",
|
||||
"agency_id",
|
||||
"product_type",
|
||||
"fare_id",
|
||||
"product_name",
|
||||
"short_name",
|
||||
"description",
|
||||
"duration",
|
||||
"transfers"
|
||||
],
|
||||
"fare_leg_rules": [
|
||||
"fare_id",
|
||||
"route_id",
|
||||
"origin_id",
|
||||
"destination_id",
|
||||
"contains_id"
|
||||
],
|
||||
"fare_transfer_rules": [
|
||||
"from_fare_id",
|
||||
"to_fare_id",
|
||||
"transfer_type",
|
||||
"min_transfer_time"
|
||||
],
|
||||
"areas": [
|
||||
"area_id",
|
||||
"area_name",
|
||||
"area_description"
|
||||
],
|
||||
"stop_areas": [
|
||||
"stop_area_id",
|
||||
"stop_id",
|
||||
"area_id",
|
||||
"location_type",
|
||||
"parent_station",
|
||||
"fare_zone_id"
|
||||
],
|
||||
"networks": [
|
||||
"network_id",
|
||||
"network_name",
|
||||
"network_description"
|
||||
],
|
||||
"route_networks": [
|
||||
"route_id",
|
||||
"network_id"
|
||||
],
|
||||
"shapes": [
|
||||
"shape_id",
|
||||
"shape_pt_lat",
|
||||
"shape_pt_lon",
|
||||
"shape_pt_sequence",
|
||||
"shape_dist_traveled"
|
||||
],
|
||||
"frequencies": [
|
||||
"trip_id",
|
||||
"start_time",
|
||||
"end_time",
|
||||
"headway_secs",
|
||||
"exact_times"
|
||||
],
|
||||
"transfers": [
|
||||
"from_stop_id",
|
||||
"to_stop_id",
|
||||
"transfer_type",
|
||||
"min_transfer_time"
|
||||
],
|
||||
"pathways": [
|
||||
"pathway_id",
|
||||
"from_stop_id",
|
||||
"to_stop_id",
|
||||
"pathway_mode",
|
||||
"is_bidirectional",
|
||||
"length",
|
||||
"traversal_time",
|
||||
"stair_count",
|
||||
"max_slope",
|
||||
"min_width",
|
||||
"signposted_as",
|
||||
"reversed_signposted_as"
|
||||
],
|
||||
"levels": [
|
||||
"level_id",
|
||||
"level_index",
|
||||
"level_name"
|
||||
],
|
||||
"location_groups": [
|
||||
"location_group_id",
|
||||
"location_group_name"
|
||||
],
|
||||
"location_group_stops": [
|
||||
"location_group_id",
|
||||
"stop_id"
|
||||
],
|
||||
"locations_geojson": [
|
||||
"type",
|
||||
"features"
|
||||
],
|
||||
"booking_rules": [
|
||||
"rule_id",
|
||||
"stop_id",
|
||||
"rule_type",
|
||||
"booking_url",
|
||||
"admission_rules",
|
||||
"admission_requirements"
|
||||
],
|
||||
"translations": [
|
||||
"table_name",
|
||||
"field_name",
|
||||
"language",
|
||||
"translation"
|
||||
],
|
||||
"feed_info": [
|
||||
"feed_publisher_name",
|
||||
"feed_publisher_url",
|
||||
"feed_lang",
|
||||
"default_lang",
|
||||
"feed_start_date",
|
||||
"feed_end_date",
|
||||
"feed_version",
|
||||
"feed_contact_email",
|
||||
"feed_contact_url"
|
||||
],
|
||||
"attributions": [
|
||||
"attribution_id",
|
||||
"organization_name",
|
||||
"is_producer"
|
||||
]
|
||||
}
|
||||
|
||||
def to_camel_case(s: str):
|
||||
return ''.join(word.capitalize() for word in s.split('_'))
|
||||
|
||||
def standardize_time(time_str):
|
||||
date_str = f"Jan 19, 1999 {time_str}"
|
||||
ntuple=email.utils.parsedate(date_str)
|
||||
timestamp=time.mktime(ntuple)
|
||||
date=datetime.datetime.fromtimestamp(timestamp)
|
||||
return date.strftime('%H:%M:%S')
|
||||
|
||||
|
||||
def is_NaN(v):
|
||||
return (isinstance(v, str) and v.lower() == "nan") or (isinstance(v, numbers.Number) and math.isnan(v))
|
||||
|
||||
def stdz(v, m, f):
|
||||
if m._meta.get_field(f).get_internal_type() == 'DateField':
|
||||
return str(v)
|
||||
if m._meta.get_field(f).get_internal_type() == 'TimeField':
|
||||
return standardize_time(v)
|
||||
return v
|
||||
|
||||
|
||||
def gtfs_to_db(g: pt_map.gtfs.GTFS):
|
||||
for k,v in gtfs_schema.items():
|
||||
name = to_camel_case(singularize(k))
|
||||
m = getattr(pt_map.models, name)
|
||||
df = getattr(g, k).data
|
||||
print("\n\n\n\n")
|
||||
print(name)
|
||||
print("#############################################################################################")
|
||||
if not df.empty:
|
||||
for _, row in df.iterrows():
|
||||
defaults = {field: stdz(row.get(field), m, field) for field in v if row.get(field) and not is_NaN(row[field])}
|
||||
kw_args = {v[0]: row[v[0]]}
|
||||
m.objects.update_or_create(
|
||||
defaults = defaults,
|
||||
**kw_args,
|
||||
)
|
||||
|
||||
|
||||
@@ -13,12 +13,29 @@ class GTFS:
|
||||
self.calendar_dates = self.CalendarDates(self.folder_path)
|
||||
self.fare_attributes = self.FareAttributes(self.folder_path)
|
||||
self.fare_rules = self.FareRules(self.folder_path)
|
||||
self.timeframes = self.Timeframes(self.folder_path)
|
||||
self.fare_media = self.FareMedia(self.folder_path)
|
||||
self.fare_products = self.FareProducts(self.folder_path)
|
||||
self.fare_leg_rules = self.FareLegRules(self.folder_path)
|
||||
self.fare_transfer_rules = self.FareTransferRules(self.folder_path)
|
||||
self.areas = self.Areas(self.folder_path)
|
||||
self.stop_areas = self.StopAreas(self.folder_path)
|
||||
self.networks = self.Networks(self.folder_path)
|
||||
self.route_networks = self.RouteNetworks(self.folder_path)
|
||||
self.shapes = self.Shapes(self.folder_path)
|
||||
self.frequencies = self.Frequencies(self.folder_path)
|
||||
self.transfers = self.Transfers(self.folder_path)
|
||||
self.pathways = self.Pathways(self.folder_path)
|
||||
self.levels = self.Levels(self.folder_path)
|
||||
self.location_groups = self.LocationGroups(self.folder_path)
|
||||
self.location_group_stops = self.LocationGroupStops(self.folder_path)
|
||||
self.locations_geojson = self.LocationsGeojson(self.folder_path)
|
||||
self.booking_rules = self.BookingRules(self.folder_path)
|
||||
self.translations = self.Translations(self.folder_path)
|
||||
self.feed_info = self.FeedInfo(self.folder_path)
|
||||
self.attributions = self.Attributions(self.folder_path)
|
||||
self.errors = []
|
||||
|
||||
|
||||
class GTFSFile:
|
||||
def __init__(self, folder_path, file_name):
|
||||
self.file_path = f"{folder_path}/{file_name}.txt"
|
||||
@@ -66,6 +83,42 @@ class GTFS:
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'fare_rules')
|
||||
|
||||
class Timeframes(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'timeframes')
|
||||
|
||||
class FareMedia(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'fare_media')
|
||||
|
||||
class FareProducts(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'fare_products')
|
||||
|
||||
class FareLegRules(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'fare_leg_rules')
|
||||
|
||||
class FareTransferRules(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'fare_transfer_rules')
|
||||
|
||||
class Areas(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'areas')
|
||||
|
||||
class StopAreas(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'stop_areas')
|
||||
|
||||
class Networks(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'networks')
|
||||
|
||||
class RouteNetworks(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'route_networks')
|
||||
|
||||
class Shapes(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'shapes')
|
||||
@@ -78,32 +131,73 @@ class GTFS:
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'transfers')
|
||||
|
||||
class Pathways(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'pathways')
|
||||
|
||||
class Levels(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'levels')
|
||||
|
||||
class LocationGroups(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'location_groups')
|
||||
|
||||
class LocationGroupStops(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'location_group_stops')
|
||||
|
||||
class LocationsGeojson(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
self.file_path = f"{folder_path}/locations.geojson"
|
||||
if os.path.exists(self.file_path):
|
||||
self.data = self.load_data()
|
||||
else:
|
||||
self.data = pd.DataFrame()
|
||||
|
||||
def load_data(self):
|
||||
try:
|
||||
return pd.read_json(self.file_path)
|
||||
except ValueError:
|
||||
return pd.DataFrame()
|
||||
|
||||
class BookingRules(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'booking_rules')
|
||||
|
||||
class Translations(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'translations')
|
||||
|
||||
class FeedInfo(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'feed_info')
|
||||
|
||||
class Attributions(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'attributions')
|
||||
|
||||
def get_files(self):
|
||||
return [attr for attr in list(set(dir(self)) - set(dir(GTFS))) if isinstance(getattr(self,attr),self.GTFSFile)]
|
||||
return [attr for attr in dir(self) if isinstance(getattr(self, attr), self.GTFSFile)]
|
||||
|
||||
def get_fields(self, name):
|
||||
file = getattr(self, name)
|
||||
if not file:
|
||||
return None
|
||||
return list(set(dir(file)) - set(dir(GTFSFile)))
|
||||
return list(file.data.columns)
|
||||
|
||||
def export(self, path, dirname):
|
||||
path = f"{os.path.normpath(path)}/{dirname}"
|
||||
if not os.path.exists(path):
|
||||
os.mkdir(path)
|
||||
print(self.get_files())
|
||||
for name in self.get_files():
|
||||
df = getattr(self, name).data
|
||||
fpath = f"{path}/{name}.txt"
|
||||
# print(f"name: {name}")
|
||||
print(name)
|
||||
df.to_csv(fpath, index=False)
|
||||
|
||||
|
||||
if name == 'locations_geojson':
|
||||
fpath = f"{path}/{name}.geojson"
|
||||
df.to_json(fpath)
|
||||
else:
|
||||
df.to_csv(fpath, index=False)
|
||||
|
||||
def validate(self):
|
||||
self.validate_agency()
|
||||
@@ -112,6 +206,30 @@ class GTFS:
|
||||
self.validate_trips()
|
||||
self.validate_stop_times()
|
||||
self.validate_calendar()
|
||||
self.validate_calendar_dates()
|
||||
self.validate_fare_attributes()
|
||||
self.validate_fare_rules()
|
||||
self.validate_timeframes()
|
||||
self.validate_fare_media()
|
||||
self.validate_fare_products()
|
||||
self.validate_fare_leg_rules()
|
||||
self.validate_fare_transfer_rules()
|
||||
self.validate_areas()
|
||||
self.validate_stop_areas()
|
||||
self.validate_networks()
|
||||
self.validate_route_networks()
|
||||
self.validate_shapes()
|
||||
self.validate_frequencies()
|
||||
self.validate_transfers()
|
||||
self.validate_pathways()
|
||||
self.validate_levels()
|
||||
self.validate_location_groups()
|
||||
self.validate_location_group_stops()
|
||||
self.validate_locations_geojson()
|
||||
self.validate_booking_rules()
|
||||
self.validate_translations()
|
||||
self.validate_feed_info()
|
||||
self.validate_attributions()
|
||||
self.validate_cross_references()
|
||||
|
||||
if not self.errors:
|
||||
@@ -120,54 +238,207 @@ class GTFS:
|
||||
return self.errors
|
||||
|
||||
def validate_agency(self):
|
||||
required_fields = ["agency_id", "agency_name", "agency_url", "agency_timezone"]
|
||||
required_fields = ["agency_name", "agency_url", "agency_timezone"]
|
||||
optional_fields = ["agency_id", "agency_lang", "agency_phone", "agency_fare_url", "agency_email"]
|
||||
self.validate_required_fields(self.agency.data, required_fields, "agency.txt")
|
||||
self.validate_optional_fields(self.agency.data, optional_fields, "agency.txt")
|
||||
|
||||
def validate_stops(self):
|
||||
required_fields = ["stop_id", "stop_name", "stop_lat", "stop_lon"]
|
||||
required_fields = ["stop_id", "stop_name"]
|
||||
optional_fields = ["stop_code", "stop_desc", "stop_lat", "stop_lon", "zone_id", "stop_url",
|
||||
"location_type", "parent_station", "stop_timezone", "wheelchair_boarding",
|
||||
"level_id", "platform_code"]
|
||||
self.validate_required_fields(self.stops.data, required_fields, "stops.txt")
|
||||
self.validate_optional_fields(self.stops.data, optional_fields, "stops.txt")
|
||||
self.validate_lat_lon(self.stops.data)
|
||||
|
||||
def validate_routes(self):
|
||||
required_fields = ["route_id", "route_short_name", "route_long_name", "route_type"]
|
||||
optional_fields = ["agency_id", "route_desc", "route_url", "route_color", "route_text_color",
|
||||
"route_sort_order", "continuous_pickup", "continuous_drop_off"]
|
||||
self.validate_required_fields(self.routes.data, required_fields, "routes.txt")
|
||||
self.validate_optional_fields(self.routes.data, optional_fields, "routes.txt")
|
||||
|
||||
def validate_trips(self):
|
||||
required_fields = ["route_id", "service_id", "trip_id"]
|
||||
optional_fields = ["trip_headsign", "trip_short_name", "direction_id", "block_id", "shape_id",
|
||||
"wheelchair_accessible", "bikes_allowed"]
|
||||
self.validate_required_fields(self.trips.data, required_fields, "trips.txt")
|
||||
self.validate_optional_fields(self.trips.data, optional_fields, "trips.txt")
|
||||
|
||||
def validate_stop_times(self):
|
||||
required_fields = ["trip_id", "arrival_time", "departure_time", "stop_id", "stop_sequence"]
|
||||
optional_fields = ["stop_headsign", "pickup_type", "drop_off_type", "shape_dist_traveled",
|
||||
"timepoint"]
|
||||
self.validate_required_fields(self.stop_times.data, required_fields, "stop_times.txt")
|
||||
self.validate_optional_fields(self.stop_times.data, optional_fields, "stop_times.txt")
|
||||
|
||||
def validate_calendar(self):
|
||||
required_fields = ["service_id", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", "start_date", "end_date"]
|
||||
required_fields = ["service_id", "monday", "tuesday", "wednesday", "thursday", "friday",
|
||||
"saturday", "sunday", "start_date", "end_date"]
|
||||
self.validate_required_fields(self.calendar.data, required_fields, "calendar.txt")
|
||||
|
||||
def validate_required_fields(self, data, required_fields, filename):
|
||||
for field in required_fields:
|
||||
if field not in data.columns:
|
||||
self.errors.append(f"Error: {filename} missing required field: {field}")
|
||||
def validate_calendar_dates(self):
|
||||
required_fields = ["service_id", "date", "exception_type"]
|
||||
self.validate_required_fields(self.calendar_dates.data, required_fields, "calendar_dates.txt")
|
||||
|
||||
def validate_lat_lon(self, data):
|
||||
for index, row in data.iterrows():
|
||||
if not (-90 <= row['stop_lat'] <= 90):
|
||||
self.errors.append(f"Error: stops.txt invalid latitude at row {index}: {row['stop_lat']}")
|
||||
if not (-180 <= row['stop_lon'] <= 180):
|
||||
self.errors.append(f"Error: stops.txt invalid longitude at row {index}: {row['stop_lon']}")
|
||||
def validate_fare_attributes(self):
|
||||
required_fields = ["fare_id", "price", "currency_type", "payment_method", "transfers"]
|
||||
optional_fields = ["agency_id", "transfer_duration"]
|
||||
self.validate_required_fields(self.fare_attributes.data, required_fields, "fare_attributes.txt")
|
||||
self.validate_optional_fields(self.fare_attributes.data, optional_fields, "fare_attributes.txt")
|
||||
|
||||
def validate_fare_rules(self):
|
||||
required_fields = ["fare_id"]
|
||||
optional_fields = ["route_id", "origin_id", "destination_id", "contains_id"]
|
||||
self.validate_required_fields(self.fare_rules.data, required_fields, "fare_rules.txt")
|
||||
self.validate_optional_fields(self.fare_rules.data, optional_fields, "fare_rules.txt")
|
||||
|
||||
def validate_timeframes(self):
|
||||
required_fields = ["timeframe_id", "start_time", "end_time"]
|
||||
optional_fields = ["timeframe_name", "timeframe_desc"]
|
||||
self.validate_required_fields(self.timeframes.data, required_fields, "timeframes.txt")
|
||||
self.validate_optional_fields(self.timeframes.data, optional_fields, "timeframes.txt")
|
||||
|
||||
def validate_fare_media(self):
|
||||
required_fields = ["media_id", "media_name", "media_type"]
|
||||
optional_fields = ["media_desc"]
|
||||
self.validate_required_fields(self.fare_media.data, required_fields, "fare_media.txt")
|
||||
self.validate_optional_fields(self.fare_media.data, optional_fields, "fare_media.txt")
|
||||
|
||||
def validate_fare_products(self):
|
||||
required_fields = ["product_id", "product_name", "product_type", "product_price", "currency"]
|
||||
optional_fields = ["product_desc"]
|
||||
self.validate_required_fields(self.fare_products.data, required_fields, "fare_products.txt")
|
||||
self.validate_optional_fields(self.fare_products.data, optional_fields, "fare_products.txt")
|
||||
|
||||
def validate_fare_leg_rules(self):
|
||||
required_fields = ["leg_id", "from_stop_id", "to_stop_id"]
|
||||
optional_fields = ["leg_desc"]
|
||||
self.validate_required_fields(self.fare_leg_rules.data, required_fields, "fare_leg_rules.txt")
|
||||
self.validate_optional_fields(self.fare_leg_rules.data, optional_fields, "fare_leg_rules.txt")
|
||||
|
||||
def validate_fare_transfer_rules(self):
|
||||
required_fields = ["from_leg_id", "to_leg_id", "transfer_type"]
|
||||
optional_fields = ["transfer_time"]
|
||||
self.validate_required_fields(self.fare_transfer_rules.data, required_fields, "fare_transfer_rules.txt")
|
||||
self.validate_optional_fields(self.fare_transfer_rules.data, optional_fields, "fare_transfer_rules.txt")
|
||||
|
||||
def validate_areas(self):
|
||||
required_fields = ["area_id", "area_name"]
|
||||
optional_fields = ["area_desc"]
|
||||
self.validate_required_fields(self.areas.data, required_fields, "areas.txt")
|
||||
self.validate_optional_fields(self.areas.data, optional_fields, "areas.txt")
|
||||
|
||||
def validate_stop_areas(self):
|
||||
required_fields = ["stop_id", "area_id"]
|
||||
optional_fields = []
|
||||
self.validate_required_fields(self.stop_areas.data, required_fields, "stop_areas.txt")
|
||||
self.validate_optional_fields(self.stop_areas.data, optional_fields, "stop_areas.txt")
|
||||
|
||||
def validate_networks(self):
|
||||
required_fields = ["network_id", "network_name"]
|
||||
optional_fields = ["network_desc"]
|
||||
self.validate_required_fields(self.networks.data, required_fields, "networks.txt")
|
||||
self.validate_optional_fields(self.networks.data, optional_fields, "networks.txt")
|
||||
|
||||
def validate_route_networks(self):
|
||||
required_fields = ["route_id", "network_id"]
|
||||
optional_fields = []
|
||||
self.validate_required_fields(self.route_networks.data, required_fields, "route_networks.txt")
|
||||
self.validate_optional_fields(self.route_networks.data, optional_fields, "route_networks.txt")
|
||||
|
||||
def validate_shapes(self):
|
||||
required_fields = ["shape_id", "shape_pt_lat", "shape_pt_lon", "shape_pt_sequence"]
|
||||
optional_fields = ["shape_dist_traveled"]
|
||||
self.validate_required_fields(self.shapes.data, required_fields, "shapes.txt")
|
||||
self.validate_optional_fields(self.shapes.data, optional_fields, "shapes.txt")
|
||||
|
||||
def validate_frequencies(self):
|
||||
required_fields = ["trip_id", "start_time", "end_time", "headway_secs"]
|
||||
optional_fields = ["exact_times"]
|
||||
self.validate_required_fields(self.frequencies.data, required_fields, "frequencies.txt")
|
||||
self.validate_optional_fields(self.frequencies.data, optional_fields, "frequencies.txt")
|
||||
|
||||
def validate_transfers(self):
|
||||
required_fields = ["from_stop_id", "to_stop_id", "transfer_type"]
|
||||
optional_fields = ["min_transfer_time"]
|
||||
self.validate_required_fields(self.transfers.data, required_fields, "transfers.txt")
|
||||
self.validate_optional_fields(self.transfers.data, optional_fields, "transfers.txt")
|
||||
|
||||
def validate_pathways(self):
|
||||
required_fields = ["pathway_id", "from_stop_id", "to_stop_id", "pathway_mode", "is_bidirectional"]
|
||||
optional_fields = ["length", "traversal_time", "stair_count", "max_slope", "min_width", "signposted_as", "reversed_signposted_as"]
|
||||
self.validate_required_fields(self.pathways.data, required_fields, "pathways.txt")
|
||||
self.validate_optional_fields(self.pathways.data, optional_fields, "pathways.txt")
|
||||
|
||||
def validate_levels(self):
|
||||
required_fields = ["level_id", "level_index"]
|
||||
optional_fields = ["level_name"]
|
||||
self.validate_required_fields(self.levels.data, required_fields, "levels.txt")
|
||||
self.validate_optional_fields(self.levels.data, optional_fields, "levels.txt")
|
||||
|
||||
def validate_location_groups(self):
|
||||
required_fields = ["location_group_id", "location_group_name"]
|
||||
optional_fields = ["location_group_desc"]
|
||||
self.validate_required_fields(self.location_groups.data, required_fields, "location_groups.txt")
|
||||
self.validate_optional_fields(self.location_groups.data, optional_fields, "location_groups.txt")
|
||||
|
||||
def validate_location_group_stops(self):
|
||||
required_fields = ["location_group_id", "stop_id"]
|
||||
optional_fields = []
|
||||
self.validate_required_fields(self.location_group_stops.data, required_fields, "location_group_stops.txt")
|
||||
self.validate_optional_fields(self.location_group_stops.data, optional_fields, "location_group_stops.txt")
|
||||
|
||||
def validate_locations_geojson(self):
|
||||
required_fields = ["type", "features"]
|
||||
optional_fields = []
|
||||
self.validate_required_fields(self.locations_geojson.data, required_fields, "locations.geojson")
|
||||
self.validate_optional_fields(self.locations_geojson.data, optional_fields, "locations.geojson")
|
||||
|
||||
def validate_booking_rules(self):
|
||||
required_fields = ["booking_rule_id"]
|
||||
optional_fields = ["booking_rule_name", "booking_rule_desc"]
|
||||
self.validate_required_fields(self.booking_rules.data, required_fields, "booking_rules.txt")
|
||||
self.validate_optional_fields(self.booking_rules.data, optional_fields, "booking_rules.txt")
|
||||
|
||||
def validate_translations(self):
|
||||
required_fields = ["table_name", "field_name", "language", "translation"]
|
||||
optional_fields = ["record_id", "record_sub_id", "field_value"]
|
||||
self.validate_required_fields(self.translations.data, required_fields, "translations.txt")
|
||||
self.validate_optional_fields(self.translations.data, optional_fields, "translations.txt")
|
||||
|
||||
def validate_feed_info(self):
|
||||
required_fields = ["feed_publisher_name", "feed_publisher_url", "feed_lang"]
|
||||
optional_fields = ["feed_start_date", "feed_end_date", "feed_version"]
|
||||
self.validate_required_fields(self.feed_info.data, required_fields, "feed_info.txt")
|
||||
self.validate_optional_fields(self.feed_info.data, optional_fields, "feed_info.txt")
|
||||
|
||||
def validate_attributions(self):
|
||||
required_fields = ["attribution_id"]
|
||||
optional_fields = ["agency_id", "route_id", "trip_id", "organization_name", "is_producer", "is_operator", "is_authority", "attribution_url", "attribution_email", "attribution_phone"]
|
||||
self.validate_required_fields(self.attributions.data, required_fields, "attributions.txt")
|
||||
self.validate_optional_fields(self.attributions.data, optional_fields, "attributions.txt")
|
||||
|
||||
def validate_required_fields(self, df, required_fields, file_name):
|
||||
missing_fields = set(required_fields) - set(df.columns)
|
||||
if missing_fields:
|
||||
self.errors.append(f"{file_name} is missing required fields: {missing_fields}")
|
||||
|
||||
def validate_optional_fields(self, df, optional_fields, file_name):
|
||||
unexpected_fields = set(df.columns) - set(optional_fields) - set(df.columns)
|
||||
if unexpected_fields:
|
||||
self.errors.append(f"{file_name} has unexpected fields: {unexpected_fields}")
|
||||
|
||||
def validate_lat_lon(self, df):
|
||||
if 'stop_lat' in df.columns and 'stop_lon' in df.columns:
|
||||
if df[['stop_lat', 'stop_lon']].isnull().any().any():
|
||||
self.errors.append(f"stops.txt has missing lat/lon values.")
|
||||
|
||||
def validate_cross_references(self):
|
||||
# Validate that trip_ids in stop_times.txt exist in trips.txt
|
||||
stop_times_trip_ids = set(self.stop_times.data['trip_id'])
|
||||
trips_trip_ids = set(self.trips.data['trip_id'])
|
||||
missing_trip_ids = stop_times_trip_ids - trips_trip_ids
|
||||
for trip_id in missing_trip_ids:
|
||||
self.errors.append(f"Error: trip_id {trip_id} in stop_times.txt does not exist in trips.txt")
|
||||
|
||||
# Validate that stop_ids in stop_times.txt exist in stops.txt
|
||||
stop_times_stop_ids = set(self.stop_times.data['stop_id'])
|
||||
stops_stop_ids = set(self.stops.data['stop_id'])
|
||||
missing_stop_ids = stop_times_stop_ids - stops_stop_ids
|
||||
for stop_id in missing_stop_ids:
|
||||
self.errors.append(f"Error: stop_id {stop_id} in stop_times.txt does not exist in stops.txt")
|
||||
# Example: Validate that all stop_ids in stop_times.txt exist in stops.txt
|
||||
if not self.stop_times.data.empty and not self.stops.data.empty:
|
||||
invalid_stops = set(self.stop_times.data['stop_id']) - set(self.stops.data['stop_id'])
|
||||
if invalid_stops:
|
||||
self.errors.append(f"stop_times.txt has invalid stop_ids: {invalid_stops}")
|
||||
|
||||
|
||||
173
transport_accessibility/pt_map/gtfs.py.bck
Normal file
173
transport_accessibility/pt_map/gtfs.py.bck
Normal file
@@ -0,0 +1,173 @@
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
class GTFS:
|
||||
def __init__(self, folder_path):
|
||||
self.folder_path = folder_path
|
||||
self.agency = self.Agency(self.folder_path)
|
||||
self.stops = self.Stops(self.folder_path)
|
||||
self.routes = self.Routes(self.folder_path)
|
||||
self.trips = self.Trips(self.folder_path)
|
||||
self.stop_times = self.StopTimes(self.folder_path)
|
||||
self.calendar = self.Calendar(self.folder_path)
|
||||
self.calendar_dates = self.CalendarDates(self.folder_path)
|
||||
self.fare_attributes = self.FareAttributes(self.folder_path)
|
||||
self.fare_rules = self.FareRules(self.folder_path)
|
||||
self.shapes = self.Shapes(self.folder_path)
|
||||
self.frequencies = self.Frequencies(self.folder_path)
|
||||
self.transfers = self.Transfers(self.folder_path)
|
||||
self.feed_info = self.FeedInfo(self.folder_path)
|
||||
self.errors = []
|
||||
|
||||
class GTFSFile:
|
||||
def __init__(self, folder_path, file_name):
|
||||
self.file_path = f"{folder_path}/{file_name}.txt"
|
||||
self.data = self.load_data()
|
||||
|
||||
def load_data(self):
|
||||
try:
|
||||
return pd.read_csv(self.file_path)
|
||||
except FileNotFoundError:
|
||||
return pd.DataFrame()
|
||||
|
||||
class Agency(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'agency')
|
||||
|
||||
class Stops(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'stops')
|
||||
|
||||
class Routes(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'routes')
|
||||
|
||||
class Trips(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'trips')
|
||||
|
||||
class StopTimes(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'stop_times')
|
||||
|
||||
class Calendar(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'calendar')
|
||||
|
||||
class CalendarDates(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'calendar_dates')
|
||||
|
||||
class FareAttributes(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'fare_attributes')
|
||||
|
||||
class FareRules(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'fare_rules')
|
||||
|
||||
class Shapes(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'shapes')
|
||||
|
||||
class Frequencies(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'frequencies')
|
||||
|
||||
class Transfers(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'transfers')
|
||||
|
||||
class FeedInfo(GTFSFile):
|
||||
def __init__(self, folder_path):
|
||||
super().__init__(folder_path, 'feed_info')
|
||||
|
||||
def get_files(self):
|
||||
return [attr for attr in list(set(dir(self)) - set(dir(GTFS))) if isinstance(getattr(self,attr),self.GTFSFile)]
|
||||
|
||||
def get_fields(self, name):
|
||||
file = getattr(self, name)
|
||||
if not file:
|
||||
return None
|
||||
return list(set(dir(file)) - set(dir(GTFSFile)))
|
||||
|
||||
def export(self, path, dirname):
|
||||
path = f"{os.path.normpath(path)}/{dirname}"
|
||||
if not os.path.exists(path):
|
||||
os.mkdir(path)
|
||||
print(self.get_files())
|
||||
for name in self.get_files():
|
||||
df = getattr(self, name).data
|
||||
fpath = f"{path}/{name}.txt"
|
||||
# print(f"name: {name}")
|
||||
print(name)
|
||||
df.to_csv(fpath, index=False)
|
||||
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.validate_agency()
|
||||
self.validate_stops()
|
||||
self.validate_routes()
|
||||
self.validate_trips()
|
||||
self.validate_stop_times()
|
||||
self.validate_calendar()
|
||||
self.validate_cross_references()
|
||||
|
||||
if not self.errors:
|
||||
return None
|
||||
else:
|
||||
return self.errors
|
||||
|
||||
def validate_agency(self):
|
||||
required_fields = ["agency_id", "agency_name", "agency_url", "agency_timezone"]
|
||||
self.validate_required_fields(self.agency.data, required_fields, "agency.txt")
|
||||
|
||||
def validate_stops(self):
|
||||
required_fields = ["stop_id", "stop_name", "stop_lat", "stop_lon"]
|
||||
self.validate_required_fields(self.stops.data, required_fields, "stops.txt")
|
||||
self.validate_lat_lon(self.stops.data)
|
||||
|
||||
def validate_routes(self):
|
||||
required_fields = ["route_id", "route_short_name", "route_long_name", "route_type"]
|
||||
self.validate_required_fields(self.routes.data, required_fields, "routes.txt")
|
||||
|
||||
def validate_trips(self):
|
||||
required_fields = ["route_id", "service_id", "trip_id"]
|
||||
self.validate_required_fields(self.trips.data, required_fields, "trips.txt")
|
||||
|
||||
def validate_stop_times(self):
|
||||
required_fields = ["trip_id", "arrival_time", "departure_time", "stop_id", "stop_sequence"]
|
||||
self.validate_required_fields(self.stop_times.data, required_fields, "stop_times.txt")
|
||||
|
||||
def validate_calendar(self):
|
||||
required_fields = ["service_id", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", "start_date", "end_date"]
|
||||
self.validate_required_fields(self.calendar.data, required_fields, "calendar.txt")
|
||||
|
||||
def validate_required_fields(self, data, required_fields, filename):
|
||||
for field in required_fields:
|
||||
if field not in data.columns:
|
||||
self.errors.append(f"Error: {filename} missing required field: {field}")
|
||||
|
||||
def validate_lat_lon(self, data):
|
||||
for index, row in data.iterrows():
|
||||
if not (-90 <= row['stop_lat'] <= 90):
|
||||
self.errors.append(f"Error: stops.txt invalid latitude at row {index}: {row['stop_lat']}")
|
||||
if not (-180 <= row['stop_lon'] <= 180):
|
||||
self.errors.append(f"Error: stops.txt invalid longitude at row {index}: {row['stop_lon']}")
|
||||
|
||||
def validate_cross_references(self):
|
||||
# Validate that trip_ids in stop_times.txt exist in trips.txt
|
||||
stop_times_trip_ids = set(self.stop_times.data['trip_id'])
|
||||
trips_trip_ids = set(self.trips.data['trip_id'])
|
||||
missing_trip_ids = stop_times_trip_ids - trips_trip_ids
|
||||
for trip_id in missing_trip_ids:
|
||||
self.errors.append(f"Error: trip_id {trip_id} in stop_times.txt does not exist in trips.txt")
|
||||
|
||||
# Validate that stop_ids in stop_times.txt exist in stops.txt
|
||||
stop_times_stop_ids = set(self.stop_times.data['stop_id'])
|
||||
stops_stop_ids = set(self.stops.data['stop_id'])
|
||||
missing_stop_ids = stop_times_stop_ids - stops_stop_ids
|
||||
for stop_id in missing_stop_ids:
|
||||
self.errors.append(f"Error: stop_id {stop_id} in stop_times.txt does not exist in stops.txt")
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-02 11:40
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pt_map', '0004_alter_agency_agency_id_alter_calendar_service_id_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Level',
|
||||
fields=[
|
||||
('level_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('level_index', models.FloatField()),
|
||||
('level_name', models.CharField(blank=True, max_length=255, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='stop',
|
||||
name='tts_stop_name',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='agency',
|
||||
name='agency_lang',
|
||||
field=models.CharField(blank=True, max_length=2, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='agency',
|
||||
name='agency_timezone',
|
||||
field=models.CharField(default=django.utils.timezone.now, max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='feedinfo',
|
||||
name='default_lang',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='feedinfo',
|
||||
name='feed_contact_email',
|
||||
field=models.EmailField(blank=True, max_length=254, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='feedinfo',
|
||||
name='feed_contact_url',
|
||||
field=models.URLField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='route',
|
||||
name='continuous_drop_off',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='route',
|
||||
name='continuous_pickup',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='route',
|
||||
name='route_sort_order',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='agency',
|
||||
name='agency_email',
|
||||
field=models.EmailField(blank=True, max_length=254, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='agency',
|
||||
name='agency_fare_url',
|
||||
field=models.URLField(blank=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='agency',
|
||||
name='agency_id',
|
||||
field=models.CharField(max_length=255, primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='agency',
|
||||
name='agency_name',
|
||||
field=models.CharField(max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='agency',
|
||||
name='agency_phone',
|
||||
field=models.CharField(blank=True, max_length=50, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='calendar',
|
||||
name='service_id',
|
||||
field=models.CharField(max_length=255, primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='calendardate',
|
||||
name='service_id',
|
||||
field=models.CharField(max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='fareattribute',
|
||||
name='currency_type',
|
||||
field=models.CharField(max_length=3),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='fareattribute',
|
||||
name='fare_id',
|
||||
field=models.CharField(max_length=255, primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='route',
|
||||
name='agency',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pt_map.agency'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='route',
|
||||
name='route_id',
|
||||
field=models.CharField(max_length=255, primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='route',
|
||||
name='route_long_name',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='route',
|
||||
name='route_short_name',
|
||||
field=models.CharField(max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='platform_code',
|
||||
field=models.CharField(blank=True, max_length=50, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='stop_code',
|
||||
field=models.CharField(blank=True, max_length=50, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='stop_desc',
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='stop_id',
|
||||
field=models.CharField(max_length=255, primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='stop_lat',
|
||||
field=models.FloatField(),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='stop_lon',
|
||||
field=models.FloatField(),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='stop_name',
|
||||
field=models.CharField(max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stop',
|
||||
name='zone_id',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stoptime',
|
||||
name='arrival_time',
|
||||
field=models.TimeField(blank=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stoptime',
|
||||
name='departure_time',
|
||||
field=models.TimeField(blank=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trip',
|
||||
name='trip_id',
|
||||
field=models.CharField(max_length=255, primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Pathway',
|
||||
fields=[
|
||||
('pathway_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('pathway_mode', models.IntegerField()),
|
||||
('is_bidirectional', models.IntegerField()),
|
||||
('length', models.FloatField(blank=True, null=True)),
|
||||
('traversal_time', models.IntegerField(blank=True, null=True)),
|
||||
('stair_count', models.IntegerField(blank=True, null=True)),
|
||||
('max_slope', models.FloatField(blank=True, null=True)),
|
||||
('min_width', models.FloatField(blank=True, null=True)),
|
||||
('signposted_as', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('reversed_signposted_as', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('from_stop', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pathways_from', to='pt_map.stop')),
|
||||
('to_stop', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pathways_to', to='pt_map.stop')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-02 12:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pt_map', '0005_level_remove_stop_tts_stop_name_agency_agency_lang_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='route',
|
||||
name='route_type',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,59 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-02 16:56
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pt_map', '0006_alter_route_route_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Location',
|
||||
fields=[
|
||||
('location_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('location_name', models.CharField(max_length=255)),
|
||||
('location_lat', models.FloatField()),
|
||||
('location_lon', models.FloatField()),
|
||||
('location_type', models.CharField(max_length=255)),
|
||||
('parent_location_id', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('wheelchair_boarding', models.BooleanField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Translation',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('table_name', models.CharField(max_length=255)),
|
||||
('field_name', models.CharField(max_length=255)),
|
||||
('language', models.CharField(max_length=2)),
|
||||
('translation', models.TextField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Attribution',
|
||||
fields=[
|
||||
('attribution_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('attribution_name', models.CharField(max_length=255)),
|
||||
('attribution_url', models.URLField()),
|
||||
('attribution_email', models.EmailField(blank=True, max_length=254, null=True)),
|
||||
('attribution_phone', models.CharField(blank=True, max_length=50, null=True)),
|
||||
('agency', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pt_map.agency')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BookingRule',
|
||||
fields=[
|
||||
('booking_rule_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('start_time', models.TimeField(blank=True, null=True)),
|
||||
('end_time', models.TimeField(blank=True, null=True)),
|
||||
('booking_type', models.CharField(max_length=255)),
|
||||
('rule_criteria', models.TextField(blank=True, null=True)),
|
||||
('booking_rule_instructions', models.TextField(blank=True, null=True)),
|
||||
('trip', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pt_map.trip')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,102 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-02 17:04
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pt_map', '0007_location_translation_attribution_bookingrule'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Area',
|
||||
fields=[
|
||||
('area_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('area_name', models.CharField(max_length=255)),
|
||||
('area_description', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FareLegRule',
|
||||
fields=[
|
||||
('fare_leg_rule_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('fare_leg_rule_name', models.CharField(max_length=255)),
|
||||
('fare_leg_rule_description', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FareMedia',
|
||||
fields=[
|
||||
('fare_media_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('fare_media_name', models.CharField(max_length=255)),
|
||||
('fare_media_description', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FareProduct',
|
||||
fields=[
|
||||
('fare_product_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('fare_product_name', models.CharField(max_length=255)),
|
||||
('fare_product_description', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FareTransferRule',
|
||||
fields=[
|
||||
('fare_transfer_rule_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('fare_transfer_rule_name', models.CharField(max_length=255)),
|
||||
('fare_transfer_rule_description', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LocationGroup',
|
||||
fields=[
|
||||
('location_group_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('location_group_name', models.CharField(max_length=255)),
|
||||
('location_group_type', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Network',
|
||||
fields=[
|
||||
('network_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('network_name', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RouteNetwork',
|
||||
fields=[
|
||||
('route_network_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('route_network_name', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StopArea',
|
||||
fields=[
|
||||
('stop_area_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('stop_area_name', models.CharField(max_length=255)),
|
||||
('stop_area_description', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TimeFrame',
|
||||
fields=[
|
||||
('time_frame_id', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||
('start_date', models.DateField()),
|
||||
('end_date', models.DateField()),
|
||||
('start_time', models.TimeField()),
|
||||
('end_time', models.TimeField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LocationGroupStop',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('location_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pt_map.locationgroup')),
|
||||
('stop', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pt_map.stop')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-02 17:10
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pt_map', '0008_area_farelegrule_faremedia_fareproduct_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='FareMedia',
|
||||
new_name='FareMedium',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-02 17:19
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pt_map', '0009_rename_faremedia_faremedium'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='Location',
|
||||
new_name='LocationGeojson',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-02 17:21
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pt_map', '0010_rename_location_locationgeojson'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='LocationGeojson',
|
||||
new_name='LocationsGeojson',
|
||||
),
|
||||
]
|
||||
@@ -1,44 +1,47 @@
|
||||
from django.db import models
|
||||
|
||||
class Agency(models.Model):
|
||||
agency_id = models.BigAutoField(primary_key=True)
|
||||
agency_name = models.CharField(max_length=250)
|
||||
agency_id = models.CharField(max_length=255, primary_key=True)
|
||||
agency_name = models.CharField(max_length=255)
|
||||
agency_url = models.URLField()
|
||||
agency_phone = models.CharField(max_length=15)
|
||||
agency_email = models.EmailField()
|
||||
agency_fare_url = models.URLField()
|
||||
agency_timezone = models.CharField(max_length=255)
|
||||
agency_lang = models.CharField(max_length=2, blank=True, null=True)
|
||||
agency_phone = models.CharField(max_length=50, blank=True, null=True)
|
||||
agency_fare_url = models.URLField(blank=True, null=True)
|
||||
agency_email = models.EmailField(blank=True, null=True)
|
||||
|
||||
class Stop(models.Model):
|
||||
stop_id = models.BigAutoField(primary_key=True)
|
||||
stop_code = models.CharField(max_length=50)
|
||||
stop_name = models.CharField(max_length=250)
|
||||
tts_stop_name = models.CharField(max_length=250)
|
||||
stop_desc = models.CharField(max_length=500)
|
||||
stop_lat = models.IntegerField()
|
||||
stop_lon = models.IntegerField()
|
||||
zone_id = models.IntegerField(unique=True)
|
||||
stop_id = models.CharField(max_length=255, primary_key=True)
|
||||
stop_code = models.CharField(max_length=50, blank=True, null=True)
|
||||
stop_name = models.CharField(max_length=255)
|
||||
stop_desc = models.TextField(blank=True, null=True)
|
||||
stop_lat = models.FloatField()
|
||||
stop_lon = models.FloatField()
|
||||
zone_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
stop_url = models.URLField(blank=True, null=True)
|
||||
location_type = models.IntegerField(blank=True, null=True)
|
||||
parent_station = models.ForeignKey('self', on_delete=models.SET_NULL, blank=True, null=True)
|
||||
stop_timezone = models.CharField(max_length=255, blank=True, null=True)
|
||||
wheelchair_boarding = models.IntegerField(blank=True, null=True)
|
||||
level_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
platform_code = models.CharField(max_length=255, blank=True, null=True)
|
||||
platform_code = models.CharField(max_length=50, blank=True, null=True)
|
||||
|
||||
|
||||
class Route(models.Model):
|
||||
route_id = models.BigAutoField(primary_key=True)
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
|
||||
route_short_name = models.CharField(max_length=255)
|
||||
route_long_name = models.CharField(max_length=255)
|
||||
route_id = models.CharField(max_length=255, primary_key=True)
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, blank=True, null=True)
|
||||
route_short_name = models.CharField(max_length=50)
|
||||
route_long_name = models.CharField(max_length=255, blank=True, null=True)
|
||||
route_desc = models.TextField(blank=True, null=True)
|
||||
route_type = models.IntegerField()
|
||||
route_type = models.IntegerField(default=0)
|
||||
route_url = models.URLField(blank=True, null=True)
|
||||
route_color = models.CharField(max_length=6, blank=True, null=True)
|
||||
route_text_color = models.CharField(max_length=6, blank=True, null=True)
|
||||
route_sort_order = models.IntegerField(blank=True, null=True)
|
||||
continuous_pickup = models.IntegerField(blank=True, null=True)
|
||||
continuous_drop_off = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Trip(models.Model):
|
||||
trip_id = models.BigAutoField(primary_key=True)
|
||||
trip_id = models.CharField(max_length=255, primary_key=True)
|
||||
route = models.ForeignKey(Route, on_delete=models.CASCADE)
|
||||
service_id = models.CharField(max_length=255)
|
||||
trip_headsign = models.CharField(max_length=255, blank=True, null=True)
|
||||
@@ -51,8 +54,8 @@ class Trip(models.Model):
|
||||
|
||||
class StopTime(models.Model):
|
||||
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
|
||||
arrival_time = models.TimeField()
|
||||
departure_time = models.TimeField()
|
||||
arrival_time = models.TimeField(blank=True, null=True)
|
||||
departure_time = models.TimeField(blank=True, null=True)
|
||||
stop = models.ForeignKey(Stop, on_delete=models.CASCADE)
|
||||
stop_sequence = models.IntegerField()
|
||||
stop_headsign = models.CharField(max_length=255, blank=True, null=True)
|
||||
@@ -65,7 +68,7 @@ class StopTime(models.Model):
|
||||
unique_together = (('trip', 'stop_sequence'),)
|
||||
|
||||
class Calendar(models.Model):
|
||||
service_id = models.BigAutoField(primary_key=True)
|
||||
service_id = models.CharField(max_length=255, primary_key=True)
|
||||
monday = models.BooleanField()
|
||||
tuesday = models.BooleanField()
|
||||
wednesday = models.BooleanField()
|
||||
@@ -77,18 +80,17 @@ class Calendar(models.Model):
|
||||
end_date = models.DateField()
|
||||
|
||||
class CalendarDate(models.Model):
|
||||
service_id = models.ForeignKey(Calendar, on_delete=models.CASCADE)
|
||||
service_id = models.CharField(max_length=255)
|
||||
date = models.DateField()
|
||||
exception_type = models.IntegerField()
|
||||
|
||||
class Meta:
|
||||
unique_together = (('service_id', 'date'),)
|
||||
|
||||
|
||||
class FareAttribute(models.Model):
|
||||
fare_id = models.BigAutoField(primary_key=True)
|
||||
fare_id = models.CharField(max_length=255, primary_key=True)
|
||||
price = models.FloatField()
|
||||
currency_type = models.CharField(max_length=255)
|
||||
currency_type = models.CharField(max_length=3)
|
||||
payment_method = models.IntegerField()
|
||||
transfers = models.IntegerField()
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, blank=True, null=True)
|
||||
@@ -123,15 +125,124 @@ class Transfer(models.Model):
|
||||
to_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='transfers_to')
|
||||
transfer_type = models.IntegerField()
|
||||
min_transfer_time = models.IntegerField(blank=True, null=True)
|
||||
|
||||
|
||||
class Meta:
|
||||
unique_together = (('from_stop', 'to_stop'),)
|
||||
|
||||
class Pathway(models.Model):
|
||||
pathway_id = models.CharField(max_length=255, primary_key=True)
|
||||
from_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='pathways_from')
|
||||
to_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='pathways_to')
|
||||
pathway_mode = models.IntegerField()
|
||||
is_bidirectional = models.IntegerField()
|
||||
length = models.FloatField(blank=True, null=True)
|
||||
traversal_time = models.IntegerField(blank=True, null=True)
|
||||
stair_count = models.IntegerField(blank=True, null=True)
|
||||
max_slope = models.FloatField(blank=True, null=True)
|
||||
min_width = models.FloatField(blank=True, null=True)
|
||||
signposted_as = models.CharField(max_length=255, blank=True, null=True)
|
||||
reversed_signposted_as = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
class Level(models.Model):
|
||||
level_id = models.CharField(max_length=255, primary_key=True)
|
||||
level_index = models.FloatField()
|
||||
level_name = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
class FeedInfo(models.Model):
|
||||
feed_publisher_name = models.CharField(max_length=255)
|
||||
feed_publisher_url = models.URLField()
|
||||
feed_lang = models.CharField(max_length=255)
|
||||
default_lang = models.CharField(max_length=255, blank=True, null=True)
|
||||
feed_start_date = models.DateField(blank=True, null=True)
|
||||
feed_end_date = models.DateField(blank=True, null=True)
|
||||
feed_version = models.CharField(max_length=255, blank=True, null=True)
|
||||
feed_contact_email = models.EmailField(blank=True, null=True)
|
||||
feed_contact_url = models.URLField(blank=True, null=True)
|
||||
feed_id = models.BigAutoField(primary_key=True)
|
||||
|
||||
class LocationsGeojson(models.Model):
|
||||
location_id = models.CharField(max_length=255, primary_key=True)
|
||||
location_name = models.CharField(max_length=255)
|
||||
location_lat = models.FloatField()
|
||||
location_lon = models.FloatField()
|
||||
location_type = models.CharField(max_length=255)
|
||||
parent_location_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
wheelchair_boarding = models.BooleanField(blank=True, null=True)
|
||||
|
||||
class BookingRule(models.Model):
|
||||
booking_rule_id = models.CharField(max_length=255, primary_key=True)
|
||||
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
|
||||
start_time = models.TimeField(blank=True, null=True)
|
||||
end_time = models.TimeField(blank=True, null=True)
|
||||
booking_type = models.CharField(max_length=255)
|
||||
rule_criteria = models.TextField(blank=True, null=True)
|
||||
booking_rule_instructions = models.TextField(blank=True, null=True)
|
||||
|
||||
class Translation(models.Model):
|
||||
table_name = models.CharField(max_length=255)
|
||||
field_name = models.CharField(max_length=255)
|
||||
language = models.CharField(max_length=2)
|
||||
translation = models.TextField()
|
||||
|
||||
class Attribution(models.Model):
|
||||
attribution_id = models.CharField(max_length=255, primary_key=True)
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
|
||||
attribution_name = models.CharField(max_length=255)
|
||||
attribution_url = models.URLField()
|
||||
attribution_email = models.EmailField(blank=True, null=True)
|
||||
attribution_phone = models.CharField(max_length=50, blank=True, null=True)
|
||||
|
||||
class LocationGroup(models.Model):
|
||||
location_group_id = models.CharField(max_length=255, primary_key=True)
|
||||
location_group_name = models.CharField(max_length=255)
|
||||
location_group_type = models.CharField(max_length=255)
|
||||
|
||||
class LocationGroupStop(models.Model):
|
||||
location_group = models.ForeignKey(LocationGroup, on_delete=models.CASCADE)
|
||||
stop = models.ForeignKey(Stop, on_delete=models.CASCADE)
|
||||
|
||||
class RouteNetwork(models.Model):
|
||||
route_network_id = models.CharField(max_length=255, primary_key=True)
|
||||
route_network_name = models.CharField(max_length=255)
|
||||
|
||||
class Network(models.Model):
|
||||
network_id = models.CharField(max_length=255, primary_key=True)
|
||||
network_name = models.CharField(max_length=255)
|
||||
|
||||
class StopArea(models.Model):
|
||||
stop_area_id = models.CharField(max_length=255, primary_key=True)
|
||||
stop_area_name = models.CharField(max_length=255)
|
||||
stop_area_description = models.TextField(blank=True, null=True)
|
||||
|
||||
class Area(models.Model):
|
||||
area_id = models.CharField(max_length=255, primary_key=True)
|
||||
area_name = models.CharField(max_length=255)
|
||||
area_description = models.TextField(blank=True, null=True)
|
||||
|
||||
class FareMedium(models.Model):
|
||||
fare_media_id = models.CharField(max_length=255, primary_key=True)
|
||||
fare_media_name = models.CharField(max_length=255)
|
||||
fare_media_description = models.TextField(blank=True, null=True)
|
||||
|
||||
class FareProduct(models.Model):
|
||||
fare_product_id = models.CharField(max_length=255, primary_key=True)
|
||||
fare_product_name = models.CharField(max_length=255)
|
||||
fare_product_description = models.TextField(blank=True, null=True)
|
||||
|
||||
class FareLegRule(models.Model):
|
||||
fare_leg_rule_id = models.CharField(max_length=255, primary_key=True)
|
||||
fare_leg_rule_name = models.CharField(max_length=255)
|
||||
fare_leg_rule_description = models.TextField(blank=True, null=True)
|
||||
|
||||
class FareTransferRule(models.Model):
|
||||
fare_transfer_rule_id = models.CharField(max_length=255, primary_key=True)
|
||||
fare_transfer_rule_name = models.CharField(max_length=255)
|
||||
fare_transfer_rule_description = models.TextField(blank=True, null=True)
|
||||
|
||||
class Timeframe(models.Model):
|
||||
time_frame_id = models.CharField(max_length=255, primary_key=True)
|
||||
start_date = models.DateField()
|
||||
end_date = models.DateField()
|
||||
start_time = models.TimeField()
|
||||
end_time = models.TimeField()
|
||||
|
||||
|
||||
137
transport_accessibility/pt_map/models.py.bck
Normal file
137
transport_accessibility/pt_map/models.py.bck
Normal file
@@ -0,0 +1,137 @@
|
||||
from django.db import models
|
||||
|
||||
class Agency(models.Model):
|
||||
agency_id = models.BigAutoField(primary_key=True)
|
||||
agency_name = models.CharField(max_length=250)
|
||||
agency_url = models.URLField()
|
||||
agency_phone = models.CharField(max_length=15)
|
||||
agency_email = models.EmailField()
|
||||
agency_fare_url = models.URLField()
|
||||
|
||||
class Stop(models.Model):
|
||||
stop_id = models.BigAutoField(primary_key=True)
|
||||
stop_code = models.CharField(max_length=50)
|
||||
stop_name = models.CharField(max_length=250)
|
||||
tts_stop_name = models.CharField(max_length=250)
|
||||
stop_desc = models.CharField(max_length=500)
|
||||
stop_lat = models.IntegerField()
|
||||
stop_lon = models.IntegerField()
|
||||
zone_id = models.IntegerField(unique=True)
|
||||
stop_url = models.URLField(blank=True, null=True)
|
||||
location_type = models.IntegerField(blank=True, null=True)
|
||||
parent_station = models.ForeignKey('self', on_delete=models.SET_NULL, blank=True, null=True)
|
||||
stop_timezone = models.CharField(max_length=255, blank=True, null=True)
|
||||
wheelchair_boarding = models.IntegerField(blank=True, null=True)
|
||||
level_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
platform_code = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
|
||||
class Route(models.Model):
|
||||
route_id = models.BigAutoField(primary_key=True)
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
|
||||
route_short_name = models.CharField(max_length=255)
|
||||
route_long_name = models.CharField(max_length=255)
|
||||
route_desc = models.TextField(blank=True, null=True)
|
||||
route_type = models.IntegerField()
|
||||
route_url = models.URLField(blank=True, null=True)
|
||||
route_color = models.CharField(max_length=6, blank=True, null=True)
|
||||
route_text_color = models.CharField(max_length=6, blank=True, null=True)
|
||||
|
||||
class Trip(models.Model):
|
||||
trip_id = models.BigAutoField(primary_key=True)
|
||||
route = models.ForeignKey(Route, on_delete=models.CASCADE)
|
||||
service_id = models.CharField(max_length=255)
|
||||
trip_headsign = models.CharField(max_length=255, blank=True, null=True)
|
||||
trip_short_name = models.CharField(max_length=255, blank=True, null=True)
|
||||
direction_id = models.IntegerField(blank=True, null=True)
|
||||
block_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
shape_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
wheelchair_accessible = models.IntegerField(blank=True, null=True)
|
||||
bikes_allowed = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class StopTime(models.Model):
|
||||
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
|
||||
arrival_time = models.TimeField()
|
||||
departure_time = models.TimeField()
|
||||
stop = models.ForeignKey(Stop, on_delete=models.CASCADE)
|
||||
stop_sequence = models.IntegerField()
|
||||
stop_headsign = models.CharField(max_length=255, blank=True, null=True)
|
||||
pickup_type = models.IntegerField(blank=True, null=True)
|
||||
drop_off_type = models.IntegerField(blank=True, null=True)
|
||||
shape_dist_traveled = models.FloatField(blank=True, null=True)
|
||||
timepoint = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (('trip', 'stop_sequence'),)
|
||||
|
||||
class Calendar(models.Model):
|
||||
service_id = models.BigAutoField(primary_key=True)
|
||||
monday = models.BooleanField()
|
||||
tuesday = models.BooleanField()
|
||||
wednesday = models.BooleanField()
|
||||
thursday = models.BooleanField()
|
||||
friday = models.BooleanField()
|
||||
saturday = models.BooleanField()
|
||||
sunday = models.BooleanField()
|
||||
start_date = models.DateField()
|
||||
end_date = models.DateField()
|
||||
|
||||
class CalendarDate(models.Model):
|
||||
service_id = models.ForeignKey(Calendar, on_delete=models.CASCADE)
|
||||
date = models.DateField()
|
||||
exception_type = models.IntegerField()
|
||||
|
||||
class Meta:
|
||||
unique_together = (('service_id', 'date'),)
|
||||
|
||||
|
||||
class FareAttribute(models.Model):
|
||||
fare_id = models.BigAutoField(primary_key=True)
|
||||
price = models.FloatField()
|
||||
currency_type = models.CharField(max_length=255)
|
||||
payment_method = models.IntegerField()
|
||||
transfers = models.IntegerField()
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, blank=True, null=True)
|
||||
transfer_duration = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class FareRule(models.Model):
|
||||
fare = models.ForeignKey(FareAttribute, on_delete=models.CASCADE)
|
||||
route = models.ForeignKey(Route, on_delete=models.CASCADE, blank=True, null=True)
|
||||
origin_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
destination_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
contains_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
class Shape(models.Model):
|
||||
shape_id = models.CharField(max_length=255)
|
||||
shape_pt_lat = models.FloatField()
|
||||
shape_pt_lon = models.FloatField()
|
||||
shape_pt_sequence = models.IntegerField()
|
||||
shape_dist_traveled = models.FloatField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (('shape_id', 'shape_pt_sequence'),)
|
||||
|
||||
class Frequency(models.Model):
|
||||
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
|
||||
start_time = models.TimeField()
|
||||
end_time = models.TimeField()
|
||||
headway_secs = models.IntegerField()
|
||||
exact_times = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Transfer(models.Model):
|
||||
from_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='transfers_from')
|
||||
to_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='transfers_to')
|
||||
transfer_type = models.IntegerField()
|
||||
min_transfer_time = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (('from_stop', 'to_stop'),)
|
||||
|
||||
class FeedInfo(models.Model):
|
||||
feed_publisher_name = models.CharField(max_length=255)
|
||||
feed_publisher_url = models.URLField()
|
||||
feed_lang = models.CharField(max_length=255)
|
||||
feed_start_date = models.DateField(blank=True, null=True)
|
||||
feed_end_date = models.DateField(blank=True, null=True)
|
||||
feed_version = models.CharField(max_length=255, blank=True, null=True)
|
||||
feed_id = models.BigAutoField(primary_key=True)
|
||||
162
transport_accessibility/pt_map/models.py.bck2
Normal file
162
transport_accessibility/pt_map/models.py.bck2
Normal file
@@ -0,0 +1,162 @@
|
||||
from django.db import models
|
||||
|
||||
class Agency(models.Model):
|
||||
agency_id = models.CharField(max_length=255, primary_key=True)
|
||||
agency_name = models.CharField(max_length=255)
|
||||
agency_url = models.URLField()
|
||||
agency_timezone = models.CharField(max_length=255)
|
||||
agency_lang = models.CharField(max_length=2, blank=True, null=True)
|
||||
agency_phone = models.CharField(max_length=50, blank=True, null=True)
|
||||
agency_fare_url = models.URLField(blank=True, null=True)
|
||||
agency_email = models.EmailField(blank=True, null=True)
|
||||
|
||||
class Stop(models.Model):
|
||||
stop_id = models.CharField(max_length=255, primary_key=True)
|
||||
stop_code = models.CharField(max_length=50, blank=True, null=True)
|
||||
stop_name = models.CharField(max_length=255)
|
||||
stop_desc = models.TextField(blank=True, null=True)
|
||||
stop_lat = models.FloatField()
|
||||
stop_lon = models.FloatField()
|
||||
zone_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
stop_url = models.URLField(blank=True, null=True)
|
||||
location_type = models.IntegerField(blank=True, null=True)
|
||||
parent_station = models.ForeignKey('self', on_delete=models.SET_NULL, blank=True, null=True)
|
||||
stop_timezone = models.CharField(max_length=255, blank=True, null=True)
|
||||
wheelchair_boarding = models.IntegerField(blank=True, null=True)
|
||||
level_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
platform_code = models.CharField(max_length=50, blank=True, null=True)
|
||||
|
||||
class Route(models.Model):
|
||||
route_id = models.CharField(max_length=255, primary_key=True)
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, blank=True, null=True)
|
||||
route_short_name = models.CharField(max_length=50)
|
||||
route_long_name = models.CharField(max_length=255, blank=True, null=True)
|
||||
route_desc = models.TextField(blank=True, null=True)
|
||||
route_type = models.IntegerField(default=0)
|
||||
route_url = models.URLField(blank=True, null=True)
|
||||
route_color = models.CharField(max_length=6, blank=True, null=True)
|
||||
route_text_color = models.CharField(max_length=6, blank=True, null=True)
|
||||
route_sort_order = models.IntegerField(blank=True, null=True)
|
||||
continuous_pickup = models.IntegerField(blank=True, null=True)
|
||||
continuous_drop_off = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Trip(models.Model):
|
||||
trip_id = models.CharField(max_length=255, primary_key=True)
|
||||
route = models.ForeignKey(Route, on_delete=models.CASCADE)
|
||||
service_id = models.CharField(max_length=255)
|
||||
trip_headsign = models.CharField(max_length=255, blank=True, null=True)
|
||||
trip_short_name = models.CharField(max_length=255, blank=True, null=True)
|
||||
direction_id = models.IntegerField(blank=True, null=True)
|
||||
block_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
shape_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
wheelchair_accessible = models.IntegerField(blank=True, null=True)
|
||||
bikes_allowed = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class StopTime(models.Model):
|
||||
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
|
||||
arrival_time = models.TimeField(blank=True, null=True)
|
||||
departure_time = models.TimeField(blank=True, null=True)
|
||||
stop = models.ForeignKey(Stop, on_delete=models.CASCADE)
|
||||
stop_sequence = models.IntegerField()
|
||||
stop_headsign = models.CharField(max_length=255, blank=True, null=True)
|
||||
pickup_type = models.IntegerField(blank=True, null=True)
|
||||
drop_off_type = models.IntegerField(blank=True, null=True)
|
||||
shape_dist_traveled = models.FloatField(blank=True, null=True)
|
||||
timepoint = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (('trip', 'stop_sequence'),)
|
||||
|
||||
class Calendar(models.Model):
|
||||
service_id = models.CharField(max_length=255, primary_key=True)
|
||||
monday = models.BooleanField()
|
||||
tuesday = models.BooleanField()
|
||||
wednesday = models.BooleanField()
|
||||
thursday = models.BooleanField()
|
||||
friday = models.BooleanField()
|
||||
saturday = models.BooleanField()
|
||||
sunday = models.BooleanField()
|
||||
start_date = models.DateField()
|
||||
end_date = models.DateField()
|
||||
|
||||
class CalendarDate(models.Model):
|
||||
service_id = models.CharField(max_length=255)
|
||||
date = models.DateField()
|
||||
exception_type = models.IntegerField()
|
||||
|
||||
class Meta:
|
||||
unique_together = (('service_id', 'date'),)
|
||||
|
||||
class FareAttribute(models.Model):
|
||||
fare_id = models.CharField(max_length=255, primary_key=True)
|
||||
price = models.FloatField()
|
||||
currency_type = models.CharField(max_length=3)
|
||||
payment_method = models.IntegerField()
|
||||
transfers = models.IntegerField()
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE, blank=True, null=True)
|
||||
transfer_duration = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class FareRule(models.Model):
|
||||
fare = models.ForeignKey(FareAttribute, on_delete=models.CASCADE)
|
||||
route = models.ForeignKey(Route, on_delete=models.CASCADE, blank=True, null=True)
|
||||
origin_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
destination_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
contains_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
class Shape(models.Model):
|
||||
shape_id = models.CharField(max_length=255)
|
||||
shape_pt_lat = models.FloatField()
|
||||
shape_pt_lon = models.FloatField()
|
||||
shape_pt_sequence = models.IntegerField()
|
||||
shape_dist_traveled = models.FloatField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (('shape_id', 'shape_pt_sequence'),)
|
||||
|
||||
class Frequency(models.Model):
|
||||
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
|
||||
start_time = models.TimeField()
|
||||
end_time = models.TimeField()
|
||||
headway_secs = models.IntegerField()
|
||||
exact_times = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Transfer(models.Model):
|
||||
from_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='transfers_from')
|
||||
to_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='transfers_to')
|
||||
transfer_type = models.IntegerField()
|
||||
min_transfer_time = models.IntegerField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (('from_stop', 'to_stop'),)
|
||||
|
||||
class Pathway(models.Model):
|
||||
pathway_id = models.CharField(max_length=255, primary_key=True)
|
||||
from_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='pathways_from')
|
||||
to_stop = models.ForeignKey(Stop, on_delete=models.CASCADE, related_name='pathways_to')
|
||||
pathway_mode = models.IntegerField()
|
||||
is_bidirectional = models.IntegerField()
|
||||
length = models.FloatField(blank=True, null=True)
|
||||
traversal_time = models.IntegerField(blank=True, null=True)
|
||||
stair_count = models.IntegerField(blank=True, null=True)
|
||||
max_slope = models.FloatField(blank=True, null=True)
|
||||
min_width = models.FloatField(blank=True, null=True)
|
||||
signposted_as = models.CharField(max_length=255, blank=True, null=True)
|
||||
reversed_signposted_as = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
class Level(models.Model):
|
||||
level_id = models.CharField(max_length=255, primary_key=True)
|
||||
level_index = models.FloatField()
|
||||
level_name = models.CharField(max_length=255, blank=True, null=True)
|
||||
|
||||
class FeedInfo(models.Model):
|
||||
feed_publisher_name = models.CharField(max_length=255)
|
||||
feed_publisher_url = models.URLField()
|
||||
feed_lang = models.CharField(max_length=255)
|
||||
default_lang = models.CharField(max_length=255, blank=True, null=True)
|
||||
feed_start_date = models.DateField(blank=True, null=True)
|
||||
feed_end_date = models.DateField(blank=True, null=True)
|
||||
feed_version = models.CharField(max_length=255, blank=True, null=True)
|
||||
feed_contact_email = models.EmailField(blank=True, null=True)
|
||||
feed_contact_url = models.URLField(blank=True, null=True)
|
||||
feed_id = models.BigAutoField(primary_key=True)
|
||||
|
||||
Reference in New Issue
Block a user