def test_import_stop_times_txt_middle_times_optional(self): stop_times_txt = StringIO.StringIO("""\ trip_id,arrival_time,departure_time,stop_id,stop_sequence STBA,6:00:00,6:00:00,STAGECOACH,1 STBA,,,STAGECOACH2,2 STBA,12:00:00,12:00:00,STAGECOACH3,3 """) stop2 = Stop.objects.create(feed=self.feed, stop_id='STAGECOACH2', lat="36.425288", lon="-117.133162") stop3 = Stop.objects.create(feed=self.feed, stop_id='STAGECOACH3', lat="36.425288", lon="-117.133162") StopTime.import_txt(stop_times_txt, self.feed) stoptime1 = StopTime.objects.get(stop=self.stop) self.assertEqual(str(stoptime1.arrival_time), '06:00:00') self.assertEqual(str(stoptime1.departure_time), '06:00:00') stoptime2 = StopTime.objects.get(stop=stop2) self.assertEqual(stoptime2.arrival_time, None) self.assertEqual(stoptime2.departure_time, None) stoptime3 = StopTime.objects.get(stop=stop3) self.assertEqual(str(stoptime3.arrival_time), '12:00:00') self.assertEqual(str(stoptime3.departure_time), '12:00:00')
def test_import_stop_times_txt_bad_column_empty_OK(self): stop_times_txt = StringIO.StringIO("""\ trip_id,arrival_time,departure_time,stop_id,stop_sequence,drop_off_time STBA,6:00:00,6:00:00,STAGECOACH,1, """) StopTime.import_txt(stop_times_txt, self.feed) stoptime = StopTime.objects.get() self.assertEqual(stoptime.trip, self.trip) self.assertEqual(str(stoptime.arrival_time), '06:00:00') self.assertEqual(str(stoptime.departure_time), '06:00:00') self.assertEqual(stoptime.stop, self.stop) self.assertEqual(stoptime.stop_sequence, 1) self.assertEqual(stoptime.drop_off_type, '')
def test_import_stop_times_txt_duplicate(self): Stop.objects.create( feed=self.feed, stop_id='XXX', point="POINT(-117.133 36.425)") stop_times_txt = StringIO("""\ trip_id,arrival_time,departure_time,stop_id,stop_sequence STBA,6:00:00,6:00:00,STAGECOACH,1 STBA,7:00:00,7:00:00,XXX,1 """) StopTime.import_txt(stop_times_txt, self.feed) stoptime = StopTime.objects.get() # Just one self.assertEqual(stoptime.trip, self.trip) self.assertEqual(str(stoptime.arrival_time), '06:00:00')
def test_import_stop_times_txt_bad_column_empty_OK(self): stop_times_txt = StringIO.StringIO("""\ trip_id,arrival_time,departure_time,stop_id,stop_sequence,drop_off_time STBA,6:00:00,6:00:00,STAGECOACH,1, """) StopTime.import_txt(stop_times_txt, self.feed) stoptime = StopTime.objects.get() self.assertEqual(stoptime.trip, self.trip) self.assertEqual(str(stoptime.arrival_time), '06:00:00') self.assertEqual(str(stoptime.departure_time), '06:00:00') self.assertEqual(stoptime.stop, self.stop) self.assertEqual(stoptime.stop_sequence, 1) self.assertEqual(stoptime.drop_off_type, '')
def test_import_stop_times_txt_minimal(self): stop_times_txt = StringIO.StringIO("""\ trip_id,arrival_time,departure_time,stop_id,stop_sequence STBA,6:00:00,6:00:00,STAGECOACH,1 """) StopTime.import_txt(stop_times_txt, self.feed) stoptime = StopTime.objects.get() self.assertEqual(stoptime.trip, self.trip) self.assertEqual(str(stoptime.arrival_time), '06:00:00') self.assertEqual(str(stoptime.departure_time), '06:00:00') self.assertEqual(stoptime.stop, self.stop) self.assertEqual(stoptime.stop_sequence, 1) self.assertEqual(stoptime.stop_headsign, '') self.assertEqual(stoptime.pickup_type, '') self.assertEqual(stoptime.drop_off_type, '') self.assertEqual(stoptime.shape_dist_traveled, None)
def test_import_stop_times_txt_minimal(self): stop_times_txt = StringIO("""\ trip_id,arrival_time,departure_time,stop_id,stop_sequence STBA,6:00:00,6:00:00,STAGECOACH,1 """) StopTime.import_txt(stop_times_txt, self.feed) stoptime = StopTime.objects.get() self.assertEqual(stoptime.trip, self.trip) self.assertEqual(str(stoptime.arrival_time), '06:00:00') self.assertEqual(str(stoptime.departure_time), '06:00:00') self.assertEqual(stoptime.stop, self.stop) self.assertEqual(stoptime.stop_sequence, 1) self.assertEqual(stoptime.stop_headsign, '') self.assertEqual(stoptime.pickup_type, '') self.assertEqual(stoptime.drop_off_type, '') self.assertEqual(stoptime.shape_dist_traveled, None)
def test_export_natural_sort(self): StopTime.objects.create( trip=self.trip, arrival_time='6:00:00', departure_time='6:00:00', stop=self.stop, stop_sequence=1, stop_headsign='SC', pickup_type=2, drop_off_type=1, shape_dist_traveled=5.25) stop2 = Stop.objects.create( feed=self.feed, stop_id='SALOON', point="POINT(-117.1 36.5)") StopTime.objects.create(trip=self.trip, stop=stop2, stop_sequence=2) stop3 = Stop.objects.create( feed=self.feed, stop_id='GENERAL_STORE', point="POINT(-117.2 36.5)") StopTime.objects.create(trip=self.trip, stop=stop3, stop_sequence=3) stop4 = Stop.objects.create( feed=self.feed, stop_id='MORGUE', point="POINT(-117.2 36.6)") StopTime.objects.create( trip=self.trip, arrival_time='7:00:00', departure_time='7:00:00', stop=stop4, stop_sequence=4, stop_headsign='MORT') stop_times_txt = StopTime.export_txt(self.feed) self.assertEqual(stop_times_txt, """\ trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,\ pickup_type,drop_off_type,shape_dist_traveled STBA,06:00:00,06:00:00,STAGECOACH,1,SC,2,1,5.25 STBA,,,SALOON,2,,,, STBA,,,GENERAL_STORE,3,,,, STBA,07:00:00,07:00:00,MORGUE,4,MORT,,, """)
def test_export_stop_times_minimal(self): StopTime.objects.create( trip=self.trip, arrival_time='6:00:00', departure_time='6:00:00', stop=self.stop, stop_sequence=1) stop_times_txt = StopTime.export_txt(self.feed) self.assertEqual(stop_times_txt, """\ trip_id,arrival_time,departure_time,stop_id,stop_sequence STBA,06:00:00,06:00:00,STAGECOACH,1 """)
def test_export_stop_times_maximal(self): StopTime.objects.create( trip=self.trip, arrival_time='6:00:00', departure_time='6:00:00', stop=self.stop, stop_sequence=1, stop_headsign='SC', pickup_type=2, drop_off_type=1, shape_dist_traveled=5.25) stop_times_txt = StopTime.export_txt(self.feed) self.assertEqual(stop_times_txt, """\ trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,\ pickup_type,drop_off_type,shape_dist_traveled STBA,06:00:00,06:00:00,STAGECOACH,1,SC,2,1,5.25 """)
def test_import_stop_times_txt_middle_times_optional(self): stop_times_txt = StringIO("""\ trip_id,arrival_time,departure_time,stop_id,stop_sequence STBA,6:00:00,6:00:00,STAGECOACH,1 STBA,,,STAGECOACH2,2 STBA,12:00:00,12:00:00,STAGECOACH3,3 """) stop2 = Stop.objects.create( feed=self.feed, stop_id='STAGECOACH2', point="POINT(-117.133162 36.425288)") stop3 = Stop.objects.create( feed=self.feed, stop_id='STAGECOACH3', point="POINT(-117.133162 36.425288)") StopTime.import_txt(stop_times_txt, self.feed) stoptime1 = StopTime.objects.get(stop=self.stop) self.assertEqual(str(stoptime1.arrival_time), '06:00:00') self.assertEqual(str(stoptime1.departure_time), '06:00:00') stoptime2 = StopTime.objects.get(stop=stop2) self.assertEqual(stoptime2.arrival_time, None) self.assertEqual(stoptime2.departure_time, None) stoptime3 = StopTime.objects.get(stop=stop3) self.assertEqual(str(stoptime3.arrival_time), '12:00:00') self.assertEqual(str(stoptime3.departure_time), '12:00:00')
def test_export_stop_times_none(self): stop_times_txt = StopTime.export_txt(self.feed) self.assertFalse(stop_times_txt)
def new_trip(request, **kwargs): route = Route.objects.get(id=kwargs.get('route_id')) # Create route + shape context = dict() context.update(kwargs) context['headsign_options'] = route.desc.split('-') context['service_times'] = Service.objects.all() if request.method == 'POST': request_params = request.POST.dict() shape_file = shapefile.Reader(shp=request.FILES['shape-file'], dbf=request.FILES['shape-file-dbf']) stops_reader = DictReaderStrip(request.FILES['stops-file']) # Check required fields are present in the stops csv expected_fields = set([ 'stop_sequence', 'lat', 'lon', 'stop_name', 'designation', 'location_type' ]) current_fields = set(stops_reader.fieldnames) if not expected_fields.issubset(current_fields): missing_fields = expected_fields.difference(current_fields) context[ 'error_message'] = 'The following columns are missing from the uploaded stops file: {}.'.format( missing_fields) return render(request, 'myapp/new-trip.html', context) # Trip variables headsign = request_params['headsign'] service_id = request_params['service-id'] direction = request_params['inbound'] route_id = kwargs['route_id'] # corridor + 4 characters for the route number corridor = route.route_id[0] route_number = route.route_id[5:9] origin = request_params['origin'] route_variation = request_params['route-variation'] shape_id = "{}{}{}{}{}".format(corridor, route_number, origin, route_variation, direction) trip_id = shape_id with transaction.atomic(): # Create new shape shape = Shape(feed_id=kwargs['feed_id'], shape_id=shape_id) shape.save() trip = Trip(trip_id=trip_id, headsign=headsign, service_id=service_id, direction=direction, route_id=route_id, shape_id=shape.id) trip.save() # Create shape points from the uploaded shape files shapes = shape_file.shapes() sequence_start = 1001 # The trip line string is stored in layer 1 for idx, point in enumerate(shapes[1].points): shape_point = ShapePoint(point='POINT ({} {})'.format( point[0], point[1]), shape_id=shape.id, sequence=sequence_start + idx) shape_point.save() shape.update_geometry() start_seconds = 6 * 3600 # First trip is at 6am delta = 5 * 60 # % minutes for row in stops_reader: tmp = list(row['stop_name'].upper().replace(' ', '')) random.shuffle(tmp) stop_suffix = "".join( tmp[:3]) # pick 3 characters from the shuffled stop name stop, created = Stop.objects.get_or_create( point=geos.fromstr('POINT({} {})'.format( row['lon'], row['lat'])), feed_id=kwargs['feed_id'], defaults={ 'stop_id': '{}{}{}{}'.format(corridor.zfill(2), row['designation'] or 0, direction, stop_suffix), 'name': row['stop_name'], 'location_type': row['location_type'], }) trip.stoptime_set.add( StopTime(stop_id=stop.id, trip_id=trip.id, stop_sequence=int(row['stop_sequence']) + 1, arrival_time=start_seconds, departure_time=start_seconds)) start_seconds += delta trip.save() trip.update_geometry() trip.refresh_from_db() return http.HttpResponseRedirect( reverse('route_detail', kwargs={ 'pk': kwargs['route_id'], 'feed_id': kwargs['feed_id'], 'agency_id': kwargs['agency_id'] })) return render(request, 'myapp/new-trip.html', context)
def trip_detail_view(request, **kwargs): context = dict() trip = Trip.objects.get(pk=kwargs['pk']) trip.update_geometry() corridor_prefix = trip.route.route_id[0].zfill(2) inbound_status = trip.direction cursor = connection.cursor() cursor.execute( "SELECT n.id, n.latitude, n.longitude FROM multigtfs_ride r JOIN multigtfs_newstop n ON(n.ride_id=r.id)" " WHERE r.route_id = " + kwargs['route_id']) columns = [column[0] for column in cursor.description] new_stops = [] for row in cursor.fetchall(): new_stops.append(dict(zip(columns, row))) new_stops = yaml.load(json.dumps(new_stops)) cursor.execute( "SELECT CONCAT(n.longitude, ' ', n.latitude) FROM multigtfs_ride r JOIN multigtfs_newroute n ON(n.ride_id=r.id)" " WHERE r.route_id = " + kwargs['route_id']) new_stops_route = [] for row in cursor.fetchall(): for i in row: i = i.encode('latin-1') i = i.translate(None, "()#") new_stops_route.append(i) stops = Stop.objects.filter(parent_station__isnull=True).order_by('name') context['agency_id'] = kwargs['agency_id'] context['feed_id'] = kwargs['feed_id'] context['route_id'] = kwargs['route_id'] context['trip'] = trip context['stops'] = stops context['corridor'] = corridor_prefix context['inbound_status'] = inbound_status context['new_stops'] = new_stops context['new_stops_route'] = new_stops_route if request.method == 'POST': start_seconds = 6 * 3600 # First trip is at 6am delta = 5 * 60 # % minutes stop_ids = request.POST.getlist('stop_id') try: with transaction.atomic(): # Delete existing stop times stop_times = trip.stoptime_set.all() for stop_time in stop_times: stop_time.delete() # Add new stop times for index, stop_id in enumerate(stop_ids): data = { 'stop_id': stop_id, 'trip_id': trip.id, 'stop_sequence': index + 1, 'arrival_time': start_seconds, 'departure_time': start_seconds } trip.stoptime_set.add(StopTime(**data)) start_seconds += delta # Delete existing route shape # trip.shape # Add new route shape except DatabaseError as e: context[ 'error_message'] = 'An error occurred while processing your request.' return http.HttpResponseRedirect(reverse('trip_detail', kwargs=kwargs)) return render(request, 'myapp/trip-detail.html', context)