Analizando los datos abiertos de Cercanias


Una vez parseado los datos abiertos de Cercanias (renfe), apuntes en Crear un parser de datos de Cercanias (Renfe) en python, se deben analizar los datos para everiguar que datos contiene, que releación tienen entre ellos y poder determinar su proposito.

Rutas o bien Lineas disponibles

En la tabla routes es donde podemos encontrar todas las lineas disponibles, haciendo un select basico para obtener todas las lineas.

SELECT routes.route_id, routes.route_short_name FROM routes

Si queremos obtener las que corresponden en C1

SELECT routes.route_id, routes.route_short_name FROM routes WHERE routes.route_short_name = "C1"

Se puede observar que se deberán filtrar por región, ya que lo ideal es obtener las C1 de una región especifica y no todas, en falta de que haya un campo identificador de region, se puede determinar como empieza el identificador route_id.

Para simplificar se crea un campo region_id que apuntará hacia una tabla regions

ALTER TABLE `routes`
	ADD COLUMN `region_id` VARCHAR(10) NOT NULL DEFAULT '0' AFTER `route_text_color`,
	ADD INDEX `region_id` (`region_id`);


SQL de creación de la tabla regions

CREATE TABLE `regions` (
	`region_id` VARCHAR(10) NOT NULL COLLATE 'utf8mb4_general_ci',
	`shortName` VARCHAR(20) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
	`longName` VARCHAR(40) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
	PRIMARY KEY (`region_id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;

Rellenar con los indentificadores de las rutas

INSERT INTO regions (regions.region_id) SELECT DISTINCT SUBSTRING(routes.route_id, 1, 2) AS region_id FROM routes;

A mano se deberá rellenar los datos faltantes, nombre corto y nombre largo, eso lo podemos extraer de la página oficial de cercanias.

10, Madrid, Madrid
20, Asturias, Asturias
30, Sevilla, Sevilla
31, Cádiz, Cadiz
32, Málaga, Málaga
40, Valencia, Valencia
41, Murcia/Alicante, Murcia y Alicante
50, Catalunya, Rodalies Catalunya
60, Bilbao, Bilbao
61, San Sebastián, San Sebastián
62, Santader, Santander
70, Zaragoza, Zaragoza

Autorellenar el valor de region_id en la tabala routes

UPDATE routes SET routes.region_id = SUBSTRING(routes.route_id, 1, 2);

Ahora para consultar las lineas disponibles de una region, por ejemplo las de Asturias que corresponden con las 20T

SELECT DISTINCT routes.route_id, routes.route_short_name FROM routes WHERE  routes.region_id = "20T";

Nos puede devolver registros huerfanos, cuando comprobamos el route_id dentro la tabla trips

Limpiar datos

Algunos registros de la tabla routes están duplicados pero sin asignación de trenes en la ruta trips, para detectar cuales están en activo.

SELECT DISTINCT routes.route_id, routes.route_short_name FROM routes
	INNER JOIN trips
		ON trips.route_id = routes.route_id
WHERE EXISTS (SELECT routes.route_id FROM routes);

Crear una columna active de tipo Bit en la tabla routes, ejecutar el siguiente SQL script, el que estén en 0, serán las rutas que no tienen ninguna asignación, con lo cual se puede descartar en las consulas futuras.

UPDATE routes SET routes.active = 1 WHERE routes.route_id IN (
SELECT DISTINCT routes.route_id FROM routes
	INNER JOIN trips
		ON trips.route_id = routes.route_id
WHERE EXISTS (SELECT routes.route_id FROM routes));

Ahora para obtener las lineas de una region debemos especificar solo las activas

SELECT routes.route_id, routes.route_short_name FROM routes WHERE routes.region_id = "20" AND routes.active = 1;

Calendario

La tabla calendario, cada entrada representa un dia y por lo que se puede apreciar, dependiendo del dia que se ha descargado los datos, solo se incluyen los datos a partir de ese dia hacia adelante.

Para obtener la fecha minima de los registros

SELECT MIN(calendar.start_date) AS start_date FROM calendar;

Para obtener la fecha máxima de los registros

SELECT MAX(calendar.start_date) AS end_date FROM calendar;

Obtener los servicios disponibles en la fecha actual

SELECT *  FROM calendar WHERE start_date = CURDATE();

Obtener los servicios en una fecha especifica, permite especificar rango de fecha inicial y fecha final

SELECT calendar.service_id FROM calendar WHERE start_date BETWEEN '2022-10-31' AND '2022-10-31';

El campo service_id es el indentificador que conjuntamente con route_id sobe la tabla trips, se puede obtener los trenes asociados a una ruta en una fecha determinada.

Paradas

En la tabla paradas, no hay complicación, están los datos de las estaciones, con su posición GPS etc.. se puede acabar de complementar datos como dirección, código postal, con el stop_id se puede recuperar una estación individual.

Por ejemplo obtener los datos de la estación Madrid Aeropuerto T4

SELECT * FROM stops WHERE stop_id = "98305";

Rutas

Obtener todas las paradas de una linea/ruta, ejemplo de C1 de Madrid

SELECT DISTINCT stop_times.stop_id , stops.stop_name
FROM stop_times
LEFT JOIN stops 
	ON stop_times.stop_id = stops.stop_id
WHERE
#	stop_times.trip_id = "1029X27201C2" 
stop_times.trip_id IN ( SELECT trips.trip_id  FROM trips WHERE trips.route_id = "10T0001C1" )
ORDER BY stop_times.stop_sequence;

Obtener el total de paradas de una ruta

SELECT COUNT(DISTINCT stops.stop_id ) AS stops_count
FROM stop_times
LEFT JOIN stops 
	ON stop_times.stop_id = stops.stop_id
WHERE stop_times.trip_id IN 
	( SELECT trips.trip_id  FROM trips 
WHERE trips.route_id = "10T0001C1" );

Obtener el viaje (trip) con más paradas, para obtener luego las paradas, en este caso la linea C2 con 19 paradas

SELECT stop_times.trip_id, COUNT(stop_times.trip_id) AS stops_count
FROM stop_times
LEFT JOIN stops 
	ON stop_times.stop_id = stops.stop_id
WHERE
	stop_times.trip_id IN ( SELECT trips.trip_id FROM trips WHERE trips.route_id = "10T0005C2" )

GROUP BY stop_times.trip_id
ORDER BY stops_count DESC LIMIT 1;

//devuelve 1032S27203C2

Ahora obtener las paradas de ese viaje con las paradas ordenadas por sequencia de parada

SELECT stop_times.trip_id, stop_times.stop_id , stops.stop_name, stop_times.departure_time, stop_times.stop_sequence
FROM stop_times
LEFT JOIN stops 
	ON stop_times.stop_id = stops.stop_id
WHERE
	stop_times.trip_id = "1032S27203C2"
ORDER BY stop_times.stop_sequence;

Horarios de los trenes

En la tabla stop_times es donde se encuentra los horarios de todos los trenes, es el eje central de los datos, por jemplo si queremos obtener los horarios de los trenes de la linea C1 de Príncipe Pío a Aeropuerto T4 , región madrid

Primero obtener el route_id con el filtro de region y nombre de linea

SELECT routes.route_id, routes.route_short_name , routes.route_long_name FROM routes WHERE routes.region_id = "10" AND routes.route_short_name = "C1" AND routes.active = 1;

devolverá dos entradas, una corresponde dirección al aeropuerto y la otra ruta a la inversa del aeropuerto hacia Príncipe Pío, nos interesa la primera route_id=10T0001C1

Obtener los servicios de trenes disponibles de la fecha actual, para comprobar si hay trenes disponibles para la linea C1 hacia el aeropuerto

SELECT calendar.service_id FROM calendar WHERE start_date = CURDATE();

Para obtener los viajes hacia el aeropuerto, se combina

SELECT stop_times.trip_id, stop_times.stop_id , stops.stop_name, stop_times.departure_time
FROM stop_times
LEFT JOIN stops 
	ON stop_times.stop_id = stops.stop_id
WHERE
stop_times.trip_id IN ( SELECT trips.trip_id  FROM trips WHERE trips.route_id = "10T0001C1" AND trips.service_id IN (SELECT calendar.service_id FROM calendar WHERE start_date BETWEEN '2022-11-02' AND '2022-11-02') )
ORDER BY trip_id, stop_times.stop_sequence;

Para obtener el viaje de un solo tren hacia un destino, en este caso con la consulta anterior obtenemos el trip_id que es 1030J27797C1

SELECT * FROM stop_times LEFT JOIN stops ON stop_times.stop_id = stops.stop_id WHERE stop_times.trip_id = "1030J27797C1";

Nos devolverá todas las estaciones del primer tren que sale de Madrid Atocha hacia el Aeropuerto, el primer registo es en las 05:15 y la llegada en Aeropuerto a las 05:44 en el último registro.

En construción….

Anuncio publicitario

Publicado por Codelaby

Mobile DevDesigner

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: