diff --git a/tpmcqr_service/api/parada.py b/tpmcqr_service/api/parada.py index 9f25375..8d3d80a 100644 --- a/tpmcqr_service/api/parada.py +++ b/tpmcqr_service/api/parada.py @@ -1,6 +1,6 @@ from flask import Blueprint, jsonify from tpmcqr_service import redis_client -from tpmcqr_service.api.utils import calcula_distancias_parada +from tpmcqr_service.api.utils import calcula_distancias_parada, parada_ruta_expediciones from time import monotonic apiv2 = Blueprint('apiv2', __name__) @@ -13,3 +13,13 @@ def info_parada(parada=None): status, salida_parada = calcula_distancias_parada(current_file, parada) salida_parada['compute_time'] = monotonic() - start_time return jsonify(salida_parada), status# from tpmcqr_service.errors.handlers import errors + + +@apiv2.route('/api_v2/stop_linea//') +def info_buses(parada=None, linea=None): + from time import monotonic + start_time = monotonic() + current_file = redis_client.get('current_file') + status, salida_parada = parada_ruta_expediciones(current_file, parada, linea) + salida_parada['compute_time'] = monotonic() - start_time + return jsonify(salida_parada), status# from tpmcqr_service.errors.handlers import errors diff --git a/tpmcqr_service/api/utils.py b/tpmcqr_service/api/utils.py index 55c09f1..b3e1627 100644 --- a/tpmcqr_service/api/utils.py +++ b/tpmcqr_service/api/utils.py @@ -5,6 +5,93 @@ import time import pickle import math +def parada_ruta_expediciones(redis_id, parada_id, lineacode): + + info_linea = dict() + + paradadb = obtiene_datos_parada(parada_id) + if not paradadb: + info_linea['debug'] = 'Invalid QR' + return 400, info_linea + + lineadb = obtiene_datos_linea(lineacode) + if not lineadb: + info_linea['debug'] = 'Invalid Lineas' + return 400, info_linea + + rt_linea = pickle.loads(redis_client.get(lineadb.id_linea)) + + if len(rt_linea['servicios']) == 0: + info_linea['debug'] = 'No data' + info_linea['servicios'] = 0 + return 400, info_linea + + rt_ppus = pickle.loads(redis_client.get('ppus')) + + for key in ['stop_name', 'stop_lat', 'stop_lon']: + info_linea[key] = getattr(paradadb, key) + + for key in ['route_short_name', 'route_long_name', 'route_color', 'route_text_color', 'lur']: + info_linea[key] = rt_linea[key] + + shape, paradas = obtiene_shape_paradas(rt_linea['id_shape'], rt_ppus[rt_linea['servicios'][0][1]]['id_trip']) + + info_linea['route_shape'] = shape + info_linea['route_stops'] = paradas + parada_pos, parada_distance = find_shape_position(rt_linea['id_shape'], paradadb.stop_lat, paradadb.stop_lon]) + info_linea['servicios'] = [] + info_linea['recientes'] = [] + + for item in rt_linea['servicios']: + + if item[0] < parada_distance: + expediciones_enruta.append(item) + else: + expediciones_pasadas.append(item) + + if len(expediciones_enruta) > 0: + expedicion = expediciones_enruta.pop(-1) + expedicion_pos = expedicion[4] + trip_shape = [{'lat': expedicion[2], 'lon': expedicion[3]}] + if expedicion_pos != parada_pos: + trip_shape += shape[expedicion_pos:parada_pos-1] + trip_shape += [{'lat': info_linea['stop_lat'], 'lon': info_linea['stop_lon']}] + + info_linea['servicios'].append( {'ppu': expedicion[1], 'trip_shape': trip_shape} ) + + if len(expediciones_enruta) > 0: + expedicion = expediciones_enruta.pop(-1) + expedicion_pos = expedicion[4] + trip_shape = [{'lat': expedicion[2], 'lon': expedicion[3]}] + if expedicion_pos != parada_pos: + trip_shape += shape[expedicion_pos:parada_pos-1] + trip_shape += [{'lat': info_linea['stop_lat'], 'lon': info_linea['stop_lon']}] + + info_linea['servicios'].append( {'ppu': expedicion[1], 'trip_shape': trip_shape} ) + + if len(expediciones_pasadas) > 0: + + expedicion = expediciones_enruta.pop(0) + expedicion_pos = expedicion[4] + trip_shape = [{'lat': info_linea['stop_lat'], 'lon': info_linea['stop_lon']}] + if expedicion_pos != parada_pos: + trip_shape += shape[parada_pos:expedicion_pos-1] + trip_shape += [{'lat': expedicion[2], 'lon': expedicion[3]}] + + info_linea['recientes'].append( {'ppu': expedicion[1], 'trip_shape': trip_shape} ) + + if len(expediciones_pasadas) > 0: + expedicion = expediciones_enruta.pop(0) + expedicion_pos = expedicion[4] + trip_shape = [{'lat': info_linea['stop_lat'], 'lon': info_linea['stop_lon']}] + if expedicion_pos != parada_pos: + trip_shape += shape[parada_pos:expedicion_pos-1] + trip_shape += [{'lat': expedicion[2], 'lon': expedicion[3]}] + + info_linea['recientes'].append( {'ppu': expedicion[1], 'trip_shape': trip_shape} ) + + + def calcula_distancias_parada(redis_id, parada_id): salida_parada = dict() @@ -26,7 +113,6 @@ def calcula_distancias_parada(redis_id, parada_id): for id_linea in obtiene_lineas_parada(devdb.id_paradero): rt_linea = pickle.loads(redis_client.get(id_linea)) - print("{}".format(rt_linea)) info_linea = dict() @@ -42,7 +128,6 @@ def calcula_distancias_parada(redis_id, parada_id): expediciones_enruta = [] expediciones_pasadas = [] for item in rt_linea['servicios']: - print("{} - {} : {} {}".format(parada_distance, item[0], type(parada_distance), type(item[0]))) if item[0] < parada_distance: expediciones_enruta.append(item) else: @@ -94,9 +179,29 @@ def estima_llegada(parada_distance, expedicion): return trip_info +def obtiene_shape_paradas(id_shape, id_trip): + shape = [] + paradas = [] -def obtiene_datos_parada(id_paradero): - parada = Paraderos.query.filter(Paraderos.id_paradero==id_paradero).one_or_none() + for item in Shapes.query.filter(Shapes.id_shape==id_shape).order_by(Shape.shape_pt_sequence.asc()).all(): + shape.append({'lat': item.shape_pt_lat, 'lon': item.shape_pt_lon}) + + for item in Paraderos.query.join(Stops).filter(Stops.id_trip==id_trip).distinct(Paraderos.id_paradero).order_by(Stops.stop_sequence.asc()).all(): + paradas.append({'name': item.stop_name, 'lat': item.stop_lat, 'lon': item.stop_lon}) + + return shape, paradas + +def obtiene_datos_parada(QRCode): + devdb = QRDev.query.filter(QRDev.id_dispositivo==QRCode).one_or_none() + if not devdb: + return None + + paradadb = Paraderos.query.filter(Paraderos.id_paradero==devdb.id_paradero).one_or_none() + + return paradadb + +def obtiene_datos_linea(codigo_linea): + parada = Lineas.query.filter(Lineas.route_short_name==id_paradero).one_or_none() if parada is None: return None return parada diff --git a/tpmcqr_service/models/gtfs.py b/tpmcqr_service/models/gtfs.py index 665500b..425f978 100644 --- a/tpmcqr_service/models/gtfs.py +++ b/tpmcqr_service/models/gtfs.py @@ -61,6 +61,7 @@ class Stops(db.Model): id_paradero = db.Column(db.String(50), db.ForeignKey('public.paradero.id_paradero'), primary_key=True) id_trip = db.Column(db.String(150), db.ForeignKey('public.gtfs_trips.id_trip'), primary_key=True) + stop_sequence = db.Column(db.Integer) def find_shape_position(shape_id, lat, lng):