tdtp_parada_v2/tpmcqr_service/models/gtfs.py

92 lines
3.4 KiB
Python
Raw Normal View History

2025-02-03 02:36:54 -03:00
from tpmcqr_service import db
from sqlalchemy.orm import aliased
from sqlalchemy import any_
from sqlalchemy import func
from geoalchemy2 import Geometry
from zoneinfo import ZoneInfo
class Lineas(db.Model):
2025-02-03 03:17:12 -03:00
__tablename__ = 'linea'
__table_args__ = { 'schema': 'public' }
2025-02-03 02:36:54 -03:00
2025-02-03 03:17:12 -03:00
id_linea = db.Column(db.String(150), primary_key=True )
id_operador = db.Column(db.String(150))
route_short_name = db.Column(db.String(150))
route_long_name = db.Column(db.String(150))
route_color = db.Column(db.String(150))
route_text_color = db.Column(db.String(150))
vigente = db.Column(db.Boolean)
2025-02-03 02:36:54 -03:00
class QRDev(db.Model):
2025-02-03 03:48:31 -03:00
__tablename__ = 'dispositivo'
2025-02-03 03:17:12 -03:00
__table_args__ = { 'schema': 'public' }
2025-02-03 02:36:54 -03:00
id_dispositivo = db.Column(db.String(100), primary_key=True )
id_paradero = db.Column(db.String(50))
2025-02-03 03:54:15 -03:00
class Paraderos(db.Model):
2025-02-03 03:51:47 -03:00
__tablename__ = 'paradero'
2025-02-03 03:17:12 -03:00
__table_args__ = { 'schema': 'public' }
2025-02-03 02:36:54 -03:00
id_paradero = db.Column(db.String(50), primary_key=True )
stop_name = db.Column(db.String(50))
stop_lat = db.Column(db.Float)
stop_lon = db.Column(db.Float)
class Shapes(db.Model):
2025-02-03 03:17:12 -03:00
__tablename__ = 'gtfs_shape'
__table_args__ = { 'schema': 'public' }
2025-02-03 02:36:54 -03:00
2025-02-03 03:17:12 -03:00
id_gtfs_pk = db.Column(db.Integer, primary_key=True )
id_shape = db.Column(db.String(150))
shape_pt_lat = db.Column(db.Float)
2025-02-03 02:36:54 -03:00
shape_pt_lon = db.Column(db.Float)
2025-02-03 03:17:12 -03:00
shape_pt_sequence = db.Column(db.Integer)
shape_dist_traveled = db.Column(db.Float)
2025-02-03 02:36:54 -03:00
2025-02-03 03:17:56 -03:00
class Trips(db.Model):
2025-02-03 03:17:12 -03:00
__tablename__ = 'gtfs_trips'
__table_args__ = { 'schema': 'public' }
2025-02-03 02:36:54 -03:00
2025-02-03 03:18:41 -03:00
id_trip = db.Column(db.String(150), primary_key=True)
id_linea = db.Column(db.String(150))
id_shape = db.Column(db.String(150))
service_id = db.Column(db.String(50))
2025-02-03 02:36:54 -03:00
def find_shape_position(shape_id, lat, lng):
Shape1 = aliased(Shapes)
Shape2 = aliased(Shapes)
point = func.ST_SetSRID(func.ST_MakePoint(lng, lat), 4326) # Create PostGIS point
2025-02-03 03:46:09 -03:00
segmento = db.session.query(
2025-02-03 02:36:54 -03:00
Shape1.shape_pt_sequence.label("start_sequence"),
2025-02-03 03:17:12 -03:00
# Shape2.shape_pt_sequence.label("end_sequence"),
2025-02-03 02:36:54 -03:00
Shape1.shape_dist_traveled.label("traveled_start"),
Shape2.shape_dist_traveled.label("traveled_end"),
func.ST_Distance(
func.ST_MakeLine(
func.ST_SetSRID(func.ST_MakePoint(Shape1.shape_pt_lon, Shape1.shape_pt_lat), 4326),
func.ST_SetSRID(func.ST_MakePoint(Shape2.shape_pt_lon, Shape2.shape_pt_lat), 4326)
),
point
).label("distance"),
func.ST_LineLocatePoint( # Compute fractional position on the segment
func.ST_MakeLine(
func.ST_SetSRID(func.ST_MakePoint(Shape1.shape_pt_lon, Shape1.shape_pt_lat), 4326),
func.ST_SetSRID(func.ST_MakePoint(Shape2.shape_pt_lon, Shape2.shape_pt_lat), 4326)
),
point
).label("fraction")
).filter(
Shape1.id_shape == shape_id,
Shape2.id_shape == shape_id,
Shape2.shape_pt_sequence == Shape1.shape_pt_sequence + 1 # Ensure correct segment order
).order_by("distance").first()
avanzado = segmento.traveled_start + segmento.fraction * (segmento.traveled_end - segmento.traveled_start)
return ( segmento.start_sequence, avanzado )