diff --git a/transport_accessibility/pt_map/class_names.py b/transport_accessibility/pt_map/class_names.py index 34a30c3..798ac09 100644 --- a/transport_accessibility/pt_map/class_names.py +++ b/transport_accessibility/pt_map/class_names.py @@ -34,7 +34,7 @@ class_names = [ "Level": pt_map.models.Level, "LocationGroup": pt_map.models.LocationGroup, "LocationGroupStop": pt_map.models.LocationGroupStop, - "LocationsGeojson": pt_map.models.LocationsGeojson, + "Location": pt_map.models.Location, "BookingRule": pt_map.models.BookingRule, "Translation": pt_map.models.Translation, "FeedInfo": pt_map.models.FeedInfo, @@ -66,7 +66,7 @@ class_names = [ "levels": pt_map.models.Level, "location_groups": pt_map.models.LocationGroup, "location_group_stops": pt_map.models.LocationGroupStop, - "locations": pt_map.models.LocationsGeojson, + "locations": pt_map.models.Location, "booking_rules": pt_map.models.BookingRule, "translations": pt_map.models.Translation, "feed_info": pt_map.models.FeedInfo, @@ -98,7 +98,7 @@ class_names = [ pt_map.models.Level: "Level", pt_map.models.LocationGroup: "LocationGroup", pt_map.models.LocationGroupStop: "LocationGroupStop", - pt_map.models.LocationsGeojson: "LocationsGeojson", + pt_map.models.Location: "Location", pt_map.models.BookingRule: "BookingRule", pt_map.models.Translation: "Translation", pt_map.models.FeedInfo: "FeedInfo", @@ -130,7 +130,7 @@ pt_map.models.Shape: "shapes", pt_map.models.Level: "levels", pt_map.models.LocationGroup: "location_groups", pt_map.models.LocationGroupStop: "location_group_stops", - pt_map.models.LocationsGeojson: "locations", + pt_map.models.Location: "locations", pt_map.models.BookingRule: "booking_rules", pt_map.models.Translation: "translations", pt_map.models.FeedInfo: "feed_info", @@ -166,7 +166,7 @@ file_names = { pt_map.models.Level: "levels.txt", pt_map.models.LocationGroup: "location_groups.txt", pt_map.models.LocationGroupStop: "location_group_stops.txt", - pt_map.models.LocationsGeojson: "locations.geojson", + pt_map.models.Location: "locations.geojson", pt_map.models.BookingRule: "booking_rules.txt", pt_map.models.Translation: "translations.txt", pt_map.models.FeedInfo: "feed_info.txt", @@ -199,7 +199,7 @@ reversed_file_mapping = { "Level": "levels", "LocationGroup": "location_groups", "LocationGroupStop": "location_group_stops", - "LocationsGeojson": "locations_geojson", + "Location": "locations_geojson", "BookingRule": "booking_rules", "Translation": "translations", "FeedInfo": "feed_info", @@ -207,7 +207,7 @@ reversed_file_mapping = { } -case_swap = {'Agency': 'agency', 'Stop': 'stops', 'Route': 'routes', 'Trip': 'trips', 'StopTime': 'stop_times', 'Calendar': 'calendar', 'CalendarDate': 'calendar_dates', 'FareAttribute': 'fare_attributes', 'FareRule': 'fare_rules', 'Timeframe': 'timeframes', 'FareMedium': 'fare_media', 'FareProduct': 'fare_products', 'FareLegRule': 'fare_leg_rules', 'FareTransferRule': 'fare_transfer_rules', 'Area': 'areas', 'StopArea': 'stop_areas', 'Network': 'networks', 'RouteNetwork': 'route_networks', 'Shape': 'shapes', 'Frequency': 'frequencies', 'Transfer': 'transfers', 'Pathway': 'pathways', 'Level': 'levels', 'LocationGroup': 'location_groups', 'LocationGroupStop': 'location_group_stops', 'LocationsGeojson': 'locations_geojson', 'BookingRule': 'booking_rules', 'Translation': 'translations', 'FeedInfo': 'feed_info', 'Attribution': 'attributions'} +case_swap = {'Agency': 'agency', 'Stop': 'stops', 'Route': 'routes', 'Trip': 'trips', 'StopTime': 'stop_times', 'Calendar': 'calendar', 'CalendarDate': 'calendar_dates', 'FareAttribute': 'fare_attributes', 'FareRule': 'fare_rules', 'Timeframe': 'timeframes', 'FareMedium': 'fare_media', 'FareProduct': 'fare_products', 'FareLegRule': 'fare_leg_rules', 'FareTransferRule': 'fare_transfer_rules', 'Area': 'areas', 'StopArea': 'stop_areas', 'Network': 'networks', 'RouteNetwork': 'route_networks', 'Shape': 'shapes', 'Frequency': 'frequencies', 'Transfer': 'transfers', 'Pathway': 'pathways', 'Level': 'levels', 'LocationGroup': 'location_groups', 'LocationGroupStop': 'location_group_stops', 'Location': 'locations_geojson', 'BookingRule': 'booking_rules', 'Translation': 'translations', 'FeedInfo': 'feed_info', 'Attribution': 'attributions'} primary_keys = { @@ -221,7 +221,7 @@ primary_keys = { pt_map.models.CalendarDate: "calendar_date_id", pt_map.models.Trip: "trip_id", pt_map.models.LocationGroup: "location_group_id", - pt_map.models.LocationsGeojson: "location_id", + pt_map.models.Location: "location_id", pt_map.models.StopTime: "stop_time_id", pt_map.models.FareAttribute: "fare_id", pt_map.models.FareRule: "fare_rule_id", @@ -255,7 +255,7 @@ classes_by_primary_keys = { 'calendar_date_id': pt_map.models.CalendarDate, 'trip_id': pt_map.models.Trip, 'location_group_id': pt_map.models.LocationGroup, - 'location_id': pt_map.models.LocationsGeojson, + 'location_id': pt_map.models.Location, 'stop_time_id': pt_map.models.StopTime, 'fare_id': pt_map.models.FareAttribute, 'fare_rule_id': pt_map.models.FareRule, @@ -288,8 +288,8 @@ foreign_keys = [ (pt_map.models.CalendarDate, [(pt_map.models.FeedInfo, 'feed_info_id'),]), (pt_map.models.Trip, [(pt_map.models.FeedInfo, 'feed_info_id'),(pt_map.models.Route, 'route_id'), (pt_map.models.Shape, 'shape_id'), ]), (pt_map.models.LocationGroup, [(pt_map.models.FeedInfo, 'feed_info_id'),]), - (pt_map.models.LocationsGeojson, [(pt_map.models.FeedInfo, 'feed_info_id'),]), - (pt_map.models.StopTime, [(pt_map.models.FeedInfo, 'feed_info_id'),(pt_map.models.Trip, 'trip_id'), (pt_map.models.Stop, 'stop_id'), (pt_map.models.LocationGroup, 'location_group_id'), (pt_map.models.LocationsGeojson, 'location_id'), ]), + (pt_map.models.Location, [(pt_map.models.FeedInfo, 'feed_info_id'),]), + (pt_map.models.StopTime, [(pt_map.models.FeedInfo, 'feed_info_id'),(pt_map.models.Trip, 'trip_id'), (pt_map.models.Stop, 'stop_id'), (pt_map.models.LocationGroup, 'location_group_id'), (pt_map.models.Location, 'location_id'), ]), (pt_map.models.FareAttribute, [(pt_map.models.FeedInfo, 'feed_info_id'),(pt_map.models.Agency, 'agency_id'), ]), (pt_map.models.FareRule, [(pt_map.models.FeedInfo, 'feed_info_id'),(pt_map.models.FareAttribute, 'fare_id'), (pt_map.models.Route, 'route_id'), ]), (pt_map.models.Frequency, [(pt_map.models.FeedInfo, 'feed_info_id'),(pt_map.models.Trip, 'trip_id'), ]), @@ -325,7 +325,7 @@ fks = { 'trip_id': pt_map.models.Trip, 'stop_id': pt_map.models.Stop, 'location_group_id': pt_map.models.LocationGroup, - 'location_id': pt_map.models.LocationsGeojson, + 'location_id': pt_map.models.Location, 'fare_id': pt_map.models.FareAttribute, 'from_stop_id': pt_map.models.Stop, 'to_stop_id': pt_map.models.Stop, diff --git a/transport_accessibility/pt_map/migrations/0022_location_alter_stoptime_location_id_and_more.py b/transport_accessibility/pt_map/migrations/0022_location_alter_stoptime_location_id_and_more.py new file mode 100644 index 0000000..474efdf --- /dev/null +++ b/transport_accessibility/pt_map/migrations/0022_location_alter_stoptime_location_id_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 5.0.6 on 2024-07-01 13:18 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pt_map', '0021_alter_stoptime_continuous_drop_off'), + ] + + operations = [ + migrations.CreateModel( + name='Location', + fields=[ + ('location_id', models.CharField(max_length=255, primary_key=True, serialize=False)), + ('stop_name', models.CharField(blank=True, max_length=255, null=True)), + ('stop_desc', models.CharField(blank=True, max_length=255, null=True)), + ('latitude', models.FloatField()), + ('longitude', models.FloatField()), + ('location_type', models.CharField(choices=[('Polygon', 'Polygon'), ('MultiPolygon', 'MultiPolygon')], max_length=255)), + ('feed_info_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pt_map.feedinfo')), + ], + ), + migrations.AlterField( + model_name='stoptime', + name='location_id', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pt_map.location'), + ), + migrations.DeleteModel( + name='LocationsGeojson', + ), + ] diff --git a/transport_accessibility/pt_map/migrations/0023_rename_location_type_location_geometry_type.py b/transport_accessibility/pt_map/migrations/0023_rename_location_type_location_geometry_type.py new file mode 100644 index 0000000..e9bf8d7 --- /dev/null +++ b/transport_accessibility/pt_map/migrations/0023_rename_location_type_location_geometry_type.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.6 on 2024-07-01 13:29 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('pt_map', '0022_location_alter_stoptime_location_id_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='location', + old_name='location_type', + new_name='geometry_type', + ), + ] diff --git a/transport_accessibility/pt_map/migrations/0024_remove_farerule_contains_id_and_more.py b/transport_accessibility/pt_map/migrations/0024_remove_farerule_contains_id_and_more.py new file mode 100644 index 0000000..6956300 --- /dev/null +++ b/transport_accessibility/pt_map/migrations/0024_remove_farerule_contains_id_and_more.py @@ -0,0 +1,40 @@ +# Generated by Django 5.0.6 on 2024-07-02 14:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pt_map', '0023_rename_location_type_location_geometry_type'), + ] + + operations = [ + migrations.RemoveField( + model_name='farerule', + name='contains_id', + ), + migrations.RemoveField( + model_name='farerule', + name='destination_id', + ), + migrations.RemoveField( + model_name='farerule', + name='origin_id', + ), + migrations.AddField( + model_name='farerule', + name='contains_id', + field=models.ManyToManyField(blank=True, null=True, related_name='fare_rules_for_zone_contains', to='pt_map.route'), + ), + migrations.AddField( + model_name='farerule', + name='destination_id', + field=models.ManyToManyField(blank=True, null=True, related_name='fare_rules_for_zone_as_destination', to='pt_map.route'), + ), + migrations.AddField( + model_name='farerule', + name='origin_id', + field=models.ManyToManyField(blank=True, null=True, related_name='fare_rules_for_zone_as_origin', to='pt_map.route'), + ), + ] diff --git a/transport_accessibility/pt_map/migrations/0025_alter_farelegrule_network_id_and_more.py b/transport_accessibility/pt_map/migrations/0025_alter_farelegrule_network_id_and_more.py new file mode 100644 index 0000000..196c22b --- /dev/null +++ b/transport_accessibility/pt_map/migrations/0025_alter_farelegrule_network_id_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 5.0.6 on 2024-07-02 14:43 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pt_map', '0024_remove_farerule_contains_id_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='farelegrule', + name='network_id', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='pt_map.network'), + ), + migrations.AlterField( + model_name='network', + name='network_name', + field=models.CharField(default='', max_length=255), + ), + migrations.AlterField( + model_name='route', + name='network_id', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='pt_map.network'), + ), + ] diff --git a/transport_accessibility/pt_map/migrations/0026_alter_farerule_contains_id_and_more.py b/transport_accessibility/pt_map/migrations/0026_alter_farerule_contains_id_and_more.py new file mode 100644 index 0000000..1c914e7 --- /dev/null +++ b/transport_accessibility/pt_map/migrations/0026_alter_farerule_contains_id_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 5.0.6 on 2024-07-02 17:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pt_map', '0025_alter_farelegrule_network_id_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='farerule', + name='contains_id', + field=models.ManyToManyField(blank=True, null=True, related_name='fare_rules_for_zone_contains', to='pt_map.stop'), + ), + migrations.AlterField( + model_name='farerule', + name='destination_id', + field=models.ManyToManyField(blank=True, null=True, related_name='fare_rules_for_zone_as_destination', to='pt_map.stop'), + ), + migrations.AlterField( + model_name='farerule', + name='origin_id', + field=models.ManyToManyField(blank=True, null=True, related_name='fare_rules_for_zone_as_origin', to='pt_map.stop'), + ), + ] diff --git a/transport_accessibility/pt_map/migrations/0027_remove_farelegrule_from_timeframe_group_id_and_more.py b/transport_accessibility/pt_map/migrations/0027_remove_farelegrule_from_timeframe_group_id_and_more.py new file mode 100644 index 0000000..6dab445 --- /dev/null +++ b/transport_accessibility/pt_map/migrations/0027_remove_farelegrule_from_timeframe_group_id_and_more.py @@ -0,0 +1,61 @@ +# Generated by Django 5.0.6 on 2024-07-02 22:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pt_map', '0026_alter_farerule_contains_id_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='farelegrule', + name='from_timeframe_group_id', + ), + migrations.RemoveField( + model_name='farelegrule', + name='to_timeframe_group_id', + ), + migrations.AlterField( + model_name='farerule', + name='contains_id', + field=models.ManyToManyField(blank=True, related_name='fare_rules_for_zone_contains', to='pt_map.stop'), + ), + migrations.AlterField( + model_name='farerule', + name='destination_id', + field=models.ManyToManyField(blank=True, related_name='fare_rules_for_zone_as_destination', to='pt_map.stop'), + ), + migrations.AlterField( + model_name='farerule', + name='origin_id', + field=models.ManyToManyField(blank=True, related_name='fare_rules_for_zone_as_origin', to='pt_map.stop'), + ), + migrations.AlterField( + model_name='stoptime', + name='drop_off_type', + field=models.IntegerField(blank=True, choices=[('Regularly scheduled drop off.', 0), ('No drop off available.', 1), ('Must phone agency to arrange drop off.', 2), ('Must coordinate with driver to arrange drop off.', 3)], null=True), + ), + migrations.AlterField( + model_name='stoptime', + name='pickup_type', + field=models.IntegerField(blank=True, choices=[('Regularly scheduled pickup.', 0), ('No pickup available.', 1), ('Must phone agency to arrange pickup.', 2), ('Must coordinate with driver to arrange pickup.', 3)], null=True), + ), + migrations.AlterField( + model_name='stoptime', + name='timepoint', + field=models.IntegerField(blank=True, choices=[('Times are considered approximate.', 0), ('Times are considered exact.', 1)], null=True), + ), + migrations.AddField( + model_name='farelegrule', + name='from_timeframe_group_id', + field=models.ManyToManyField(null=True, related_name='fare_leg_rules_from', to='pt_map.timeframe'), + ), + migrations.AddField( + model_name='farelegrule', + name='to_timeframe_group_id', + field=models.ManyToManyField(null=True, related_name='fare_leg_rules_to', to='pt_map.timeframe'), + ), + ] diff --git a/transport_accessibility/pt_map/model_test_fields.py b/transport_accessibility/pt_map/model_test_fields.py index cc25d99..868d5b2 100644 --- a/transport_accessibility/pt_map/model_test_fields.py +++ b/transport_accessibility/pt_map/model_test_fields.py @@ -206,8 +206,8 @@ field_requirements = \ }, { "name": "network_id", - "type": "mtm", - "references": Route, + "type": "fk", + "references": Network, "required": "false", "forbidden_if": ["RouteNetwork", True] }, @@ -252,8 +252,7 @@ field_requirements = \ }, { "name": "block_id", - "type": "mtm", - "references": Trip, + "type": "unique", "required": "false", }, { @@ -277,6 +276,42 @@ field_requirements = \ ], "pk": "trip_id", }, + { + "model": "Location", + "fields": [ + { + "name": "location_id", + "type": "pk", + "required": "true", + }, + { + "name": "stop_name", + "type": "str", + "required": "false", + }, + { + "name": "stop_desc", + "type": "str", + "required": "false", + }, + { + "name": "geometry_type", + "type": "enum", + "allowed_values": ["Polygon", "MultiPolygon"], + "required": "true", + }, + { + "name": "latitude", + "type": "lat", + "required": "true" + }, + { + "name": "longitude", + "type": "lon", + "required": "true", + }, + ], + }, { "model": "StopTime", "fields": [ @@ -308,7 +343,7 @@ field_requirements = \ }, { "name": "location_group_id", - "type": "mtm", + "type": "fk", "references": LocationGroup, "required": "false", "forbidden_if_not": [(["stop_id", None], ["location_id", None])], @@ -317,7 +352,7 @@ field_requirements = \ "name": "location_id", "type": "fk", "required": "false", - "references": LocationsGeojson, + "references": Location, "forbidden_if_not": [(["stop_id", None], ["location_group_id", None])], }, { @@ -658,7 +693,8 @@ field_requirements = \ }, { "name": "network_id", - "type": "str", + "type": "fk", + "references": Network, "required": "false", }, { diff --git a/transport_accessibility/pt_map/models.py b/transport_accessibility/pt_map/models.py index f25c35a..bc90c50 100644 --- a/transport_accessibility/pt_map/models.py +++ b/transport_accessibility/pt_map/models.py @@ -7,7 +7,7 @@ Attributes ---------- Classes ------- -Agency, Stop, Route, Trip, StopTime, Calendar, CalendarDate, FareAttribute, FareRule, Shape, Frequency, Transfer, Pathway, Level, FeedInfo, LocationsGeojson, BookingRule, Translation, Attribution, LocationGroup, LocationGroupStop, RouteNetwork, Network, StopArea, Area, FareMedium, FareProduct, FareLegRule, FareTransferRule, Timeframe +Agency, Stop, Route, Trip, StopTime, Calendar, CalendarDate, FareAttribute, FareRule, Shape, Frequency, Transfer, Pathway, Level, FeedInfo, Location, BookingRule, Translation, Attribution, LocationGroup, LocationGroupStop, RouteNetwork, Network, StopArea, Area, FareMedium, FareProduct, FareLegRule, FareTransferRule, Timeframe Different files as described in the GTFS Reference """ from django.db import models @@ -72,6 +72,14 @@ class Stop(models.Model): platform_code = models.CharField(max_length=50, blank=True, null=True) feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) +class Network(models.Model): + """ + Represents network.txt from the GTFS Reference. + """ + network_id = models.CharField(max_length=255, primary_key=True) + network_name = models.CharField(max_length=255, default="") + feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) + class Route(models.Model): """ Represents route.txt from the GTFS Reference. @@ -88,7 +96,7 @@ class Route(models.Model): route_sort_order = models.IntegerField(blank=True, null=True) continuous_pickup = models.IntegerField(choices=[("Continous stopping pickup", 0), ("No continuous stopping pickup", 1), ("Must phone agency to arrange continuous stopping pickup off", 2), ("Must coordinate with driver to arrange continuous stopping pickup", 3)], blank=True, null=True) continuous_drop_off = models.IntegerField(choices=[("Continous stopping pickup", 0), ("No continuous stopping pickup", 1), ("Must phone agency to arrange continuous stopping pickup off", 2), ("Must coordinate with driver to arrange continuous stopping pickup", 3)], blank=True, null=True) - network_id = models.IntegerField(blank=True, null=True) + network_id = models.ForeignKey(Network, on_delete=models.CASCADE, null=True) feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) class Shape(models.Model): @@ -175,17 +183,16 @@ class LocationGroup(models.Model): location_group_type = models.CharField(max_length=255) feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) -class LocationsGeojson(models.Model): +class Location(models.Model): """ Represents locations.geojson from the GTFS Reference. """ 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) + stop_name = models.CharField(max_length=255, blank=True, null=True) + stop_desc = models.CharField(max_length=255, blank=True, null=True) + latitude = models.FloatField() + longitude = models.FloatField() + geometry_type = models.CharField(max_length=255, choices=[("Polygon", "Polygon"), ("MultiPolygon", "MultiPolygon")]) feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) class BookingRule(models.Model): @@ -219,13 +226,13 @@ class StopTime(models.Model): departure_time = models.CharField(max_length=255, blank=True, null=True) stop_id = models.ForeignKey(Stop, null=True, on_delete=models.CASCADE) location_group_id = models.ForeignKey(LocationGroup, on_delete=models.SET_NULL, blank=True, null=True) - location_id = models.ForeignKey(LocationsGeojson, on_delete=models.SET_NULL, blank=True, null=True) + location_id = models.ForeignKey(Location, on_delete=models.SET_NULL, blank=True, null=True) 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) + pickup_type = models.IntegerField(blank=True, null=True, choices=[("Regularly scheduled pickup.", 0), ("No pickup available.", 1), ("Must phone agency to arrange pickup.", 2), ("Must coordinate with driver to arrange pickup.", 3)]) + drop_off_type = models.IntegerField(blank=True, null=True, choices=[("Regularly scheduled drop off.", 0), ("No drop off available.", 1), ("Must phone agency to arrange drop off.", 2), ("Must coordinate with driver to arrange drop off.", 3)]) shape_dist_traveled = models.FloatField(blank=True, null=True) - timepoint = models.IntegerField(blank=True, null=True) + timepoint = models.IntegerField(blank=True, null=True, choices=[("Times are considered approximate.", 0), ("Times are considered exact.", 1)]) start_pickup_drop_off_window = models.CharField(max_length=255, blank=True) end_pickup_drop_off_window = models.CharField(max_length=255, blank=True) continuous_pickup = models.IntegerField(choices=[("Continous stopping pickup", 0), ("No continuous stopping pickup", 1), ("Must phone agency to arrange continuous stopping pickup off", 2), ("Must coordinate with driver to arrange continuous stopping pickup", 3)], null=True) @@ -257,9 +264,9 @@ class FareRule(models.Model): fare_rule_id = models.BigAutoField(primary_key=True) fare_id = models.ForeignKey(FareAttribute, on_delete=models.CASCADE) route_id = models.ForeignKey(Route, on_delete=models.CASCADE, blank=True, null=True) - origin_id = models.IntegerField(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) + origin_id = models.ManyToManyField(Stop, related_name="fare_rules_for_zone_as_origin", blank=True) + destination_id = models.ManyToManyField(Stop, related_name="fare_rules_for_zone_as_destination", blank=True) + contains_id = models.ManyToManyField(Stop, related_name="fare_rules_for_zone_contains", blank=True) feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) class Frequency(models.Model): @@ -351,14 +358,6 @@ class LocationGroupStop(models.Model): stop_id = models.ForeignKey(Stop, on_delete=models.CASCADE) feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) -class Network(models.Model): - """ - Represents network.txt from the GTFS Reference. - """ - network_id = models.CharField(max_length=255, primary_key=True) - network_name = models.CharField(max_length=255) - feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) - class RouteNetwork(models.Model): """ Represents route_network.txt from the GTFS Reference. @@ -431,11 +430,11 @@ class FareLegRule(models.Model): fare_leg_rule_name = models.CharField(max_length=255) fare_leg_rule_description = models.TextField(blank=True, null=True) leg_group_id = models.CharField(max_length=255, blank=True, null=True) - network_id = models.CharField(max_length=255, blank=True, null=True) + network_id = models.ForeignKey(Network, on_delete=models.CASCADE, null=True) from_area_id = models.ForeignKey(Area, blank=True, null=True, on_delete=models.SET_NULL, related_name='farelegrule_from_area') to_area_id = models.ForeignKey(Area, blank=True, null=True, on_delete=models.SET_NULL, related_name='farelegrule_to_area') - from_timeframe_group_id = models.ForeignKey(Timeframe, blank=True, null=True, on_delete=models.SET_NULL, related_name='farelegrule_from_timeframe') - to_timeframe_group_id = models.ForeignKey(Timeframe, blank=True, null=True, on_delete=models.SET_NULL, related_name='farelegrule_to_timeframe') + from_timeframe_group_id = models.ManyToManyField(Timeframe, related_name="fare_leg_rules_from", blank=True) + to_timeframe_group_id = models.ManyToManyField(Timeframe, related_name="fare_leg_rules_to", blank=True) fare_product_id = models.ForeignKey(FareProduct, on_delete=models.CASCADE) rule_priority = models.IntegerField(blank=True, null=True) feed_info_id = models.ForeignKey(FeedInfo, on_delete=models.CASCADE) diff --git a/transport_accessibility/pt_map/templates/base.html b/transport_accessibility/pt_map/templates/base.html new file mode 100644 index 0000000..e695794 --- /dev/null +++ b/transport_accessibility/pt_map/templates/base.html @@ -0,0 +1,52 @@ +{% load static %} + + +
+ + +