-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgtfs.qmd
365 lines (259 loc) · 15.6 KB
/
gtfs.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
---
# title: "GTFS"
format:
pdf:
prefer-html: true
---
## GTFS
O General Transit Feed Specification (GTFS) é um [formato normalizado](https://gtfs.org/documentation/schedule/reference/) de dados abertos para documentar informações sobre transportes públicos, incluindo: itinerários, horários, localizações de paragens, padrões de calendário, viagens e possíveis transbordos.
As operadoras de transporte público são responsáveis por manter os dados actualizados[^gtfs-1].
[^gtfs-1]: Dados de operadora de transportes que não estejam atualizados poderão levar a uma péssima experiência ao utilizador, uma vez que a realidade não corresponde às expetativas criadas pelos dados (desatualizados).
{{< video https://youtu.be/SDz2460AjNo >}}
Os dados GTFS são utilizados em várias aplicações, como o Google Maps, City Mapper, entre outros, para fornecer direcções de transportes públicos.
Podem ser disponibilizadas para uma cidade, uma região ou mesmo um país inteiro, dependendo da operadora de TP.
Os dados encontram-se num ficheiro `.zip` que inclui vários ficheiros `.txt` (um para cada tipo de informação) com relações tabulares (campos comuns).
Os mesmos podem ser facilmente editados em qualquer computador.
![Estrutura de um ficheiro GTFS. Fonte: trilliumtransit.com](images/clipboard-2676687965.png){fig-align="center" width="493"}
[![Campos e identificador comum dos ficheiros GTFS. Fonte: Trafiklab.se](images/clipboard-3620523136.png)](https://www.trafiklab.se/api/gtfs-datasets/overview/)
Os GTFS podem ser **estáticos** (ou agendados / *schedule*) - por exemplo para viagens tabeladas, ou em **tempo real** (*real time*) - inclui mais informação, tal como **posicionamento em tempo real**.
## GTFS-Schedule
O GTFS Schedule é uma especificação que define um formato comum para informações estáticas sobre transportes públicos (agendadas, ou que não alteram dinamicamente).
Cada ficheiro descreve informação sobre transportes, como paragens, percursos, viagens, etc.
Na sua forma mais simples, um conjunto de dados GTFS é composto por 7 ficheiros:
- `agency.txt`
- `routes.txt`
- `trips.txt`
- `stops.txt`
- `stop_times.txt`
- `calendar.txt`
- `calendar_dates.txt`
## GTFS-Realtime
Os GTFS Realtime é uma norma que permite às operadoras de transportes públicos fornecer informações actualizadas sobre as horas de chegada e partida, alertas de serviço e posição dos veículos, permitindo aos utilizadores planear as suas viagens com maior detalhe, incluindo por exemplo os seguintes tipos de informação:
- **Actualizações de viagens** - atrasos, cancelamentos, alteração de itinerários
- **Alertas de serviço** - paragens deslocadas, acontecimentos imprevistos que afectem uma estação, um itinerário ou toda a rede
- **Posições dos veículos** - informações sobre os veículos, incluindo a localização e o nível de ocupação do interior do veículo
Um exemplo de GTFS-Realtime são os dados da [Carris Metropolitana](https://api.carrismetropolitana.pt/gtfs).
![Planeador de percursos em tempo real da Carris Metropolitana.](images/clipboard-123053131.png)
![Posicionamento em tempo real de autocarros Carris com passagem no Saldanha. Fonte: Google Maps](images/clipboard-1057604246.png){fig-align="center" width="298"}
## Fontes online de dados GTFS
Os seguintes websites incluem vários GTFS de operadoras, a **nível mundial**.
Uma vantagem destes agregadores de dados é que muitas vezes também disponibilizam **versões** por data - útil para análises do ano X.
- [TransitLand](https://www.transit.land)
- [Mobility Database](https://mobilitydatabase.org/)
Algumas operadoras de Transporte Público nacionais também disponibilizam os seus dados abertos nos websites.
([Ver NAP Portugal](open-data.qmd#nap))
::: {.callout-note appearance="simple"}
Podemos juntar vários GTFS`.zip` num único MegaGTFS`.zip`
:::
## Pacotes de R
Existem alguns bons pacotes R para ler e manipular dados GTFS, tais como:
- [`tidytransit`](https://r-transit.github.io/tidytransit/)
- [`gtfstools`](https://ipeagit.github.io/gtfstools/)
- [`gtfsio`](https://r-transit.github.io/gtfsio/index.html)
- [`gtfsrouter`](https://urbananalyst.github.io/gtfsrouter/) - útil para criar tabela `transfers.txt` quando não existe.
- [`geotransit`](https://github.com/tripwright/geotransit) - para descarregar todos os GTFS presentes numa determinada área
- [`GTFSwizard`](https://opatp.github.io/GTFSwizard/) - análises rápidas e interativas
::: {.callout-caution appearance="simple"}
Atenção que os pacotes podem partilhar os mesmos nomes de funções, pelo que é importante utilizar um delas de cada vez.
:::
## Exemplo em R
### Metro Lisboa
Vamos importar os dados de GTFS [diretamente](https://www.metrolisboa.pt/google_transit/googleTransit.zip) do website do Metro de Lisboa
```{r}
#| message: false
#| fig-format: png
## Pacotes
library(tidyverse)
library(tidytransit)
library(mapview)
# Ler dados GTFS
METRO = read_gtfs("https://github.com/rosamfelix/PGmob360/releases/download/2024.11/metro_gtfs.zip")
summary(METRO)
```
Este ficheiro inclui as transferências, mas não inclui as rotas.
Neste caso não é relevante, elas podem ser depois geradas com a informação que já existe.
Podemos ver a localização das 50 estações do Metro:
```{r}
#| code-fold: true
#| fig-format: png
ESTACOES_metro = stops_as_sf(METRO$stops) # converter texto para geometria
mapview(ESTACOES_metro)
```
**Desafio:** Ver quanto tempo demora a alcançar cada estação a partir da Baixa
1. num dia útil em hora de ponta
2. num domingo de noite
#### Dia útil em hora de ponta
Filtramos os dados para o dia de hoje, quarta-feira, entre as 7h30 e as 9h00, e calculamos a duração da viagem mais rápida entre a estação Baixa-Chiado e todas as outras.
```{r}
stop_times_metro = filter_stop_times(METRO, "2024-11-20", "07:30:00", "09:00:00")
duracao_viagem = travel_times(stop_times_metro, "Baixa / Chiado") # Baixa / Chiado é a estação de metro da Baixa
summary(duracao_viagem$travel_time/60) # resumo em minutos
```
Sem contar com o tempo de espera na Baixa-Chiado, é possível alcançar qualquer estação da rede **em menos de** 26.5 minutos, em hora de ponta.
#### Domingo de noite
Filtramos os dados para o próximo Domingo entre as 21h30 e as 22h30, e novamente calculamos a duração da viagem mais rápida entre a estação Baixa-Chiado e todas as outras
```{r}
stop_times_metro = filter_stop_times(METRO, "2024-11-24", "21:30:00", "22:30:00")
duracao_viagem = travel_times(stop_times_metro, "Baixa / Chiado")
summary(duracao_viagem$travel_time/60) # resumo em minutos
```
Num Domingo de noite, é possível alcançar qualquer estação da rede **em menos de** 32.3 minutos.
#### Visualizar dados num mapa
```{r}
#| include: false
# Limite município Lisboa
MunicipiosGEO = sf::st_read("data/Municipalities_geo.gpkg")
LisboaGEO = MunicipiosGEO |> filter(Municipality == "Lisboa")
```
Podemos criar um gráfico que mostre o tempo que cada estação demora a alcançar, a partir da Baixa-Chiado.
Juntamos primeiro os tempos estimados aos dados georreferenciados das estações
```{r}
#| code-fold: true
duracao_viagem_BC_HP = ESTACOES_metro |>
left_join(duracao_viagem, by = c("stop_id" = "to_stop_id")) |> # juntar os dados às estaçoes
filter(!is.na(travel_time)) # remover as plataformas não usadas
```
E "colorimos" o tempo de viagem que demora (*no mínímo*) a alcançar cada estação
```{r}
#| code-fold: true
##| code-summary: "Mostrar código"
ggplot(duracao_viagem_BC_HP) +
geom_sf(aes(color = travel_time/60)) +
ggtitle("Alcance desde a estação Baixa-Chiado (Metro)",
subtitle = "às 7h30 de Quarta, 20 Nov 2024") +
labs(color = "Tempo de viagem [min]") +
geom_sf(data = LisboaGEO, # limite Lisboa
fill = "transparent",
color = "grey30") +
theme_bw()
```
### Carris Lisboa
Podemos fazer o mesmo exercício com os [dados da Carris](https://gateway.carris.pt/gateway/gtfs/api/v2.8/GTFS).
O ficheiro original não inclui o transfers.txt, e foi gerado automaticamente um com a função [`gtfsrouter::gtfs_transfer_table()`](https://urbananalyst.github.io/gtfsrouter/reference/gtfs_transfer_table.html)
```{r}
#| message: false
# Ler dados GTFS
CARRIS = read_gtfs("https://github.com/rosamfelix/PGmob360/releases/download/2024.11/carris_gtfs.zip")
summary(CARRIS)
```
Este ficheiro já inclui as transferências, e também as rotas.
Podemos ver a localização das 2313 estações da Carris:
```{r}
#| code-fold: true
#| fig-format: png
ESTACOES_carris = stops_as_sf(CARRIS$stops) # converter texto para geometria
mapview(ESTACOES_carris)
```
E as 1739 rotas (inclui variantes, idas e voltas):
```{r}
#| code-fold: true
#| fig-format: png
ROTAS_carris = shapes_as_sf(CARRIS$shapes) # converter texto para geometria
mapview(ROTAS_carris, zcol = "shape_id") # visualizar
```
Vamos fazer o mesmo **desafio**, mas com origem nas paragens do Cais do Sodré.
#### Dia útil em hora de ponta
Filtramos os dados para o dia de hoje, quarta-feira, entre as 7h30 e as 9h00, e calculamos a duração da viagem mais rápida entre a estação Baixa-Chiado e todas as outras.
```{r}
stop_times_carris1 = filter_stop_times(CARRIS, "2024-11-20", "07:30:00", "09:00:00")
duracao_viagem1 = travel_times(stop_times_carris1, "Cais Sodré", stop_dist_check = FALSE)
nrow(duracao_viagem1)
summary(duracao_viagem1$travel_time/60) # resumo em minutos
```
Sem contar com o tempo de espera na Baixa-Chiado, é possível alcançar 1114 estações da rede (48%) **em menos de** 82 minutos (1h22), em hora de ponta - no intervalo de 1h30 definido.
##### **Outras estatísticas**
```{r}
hist(duracao_viagem1$travel_time/60, breaks = 20) # histograma
abline(v = mean(duracao_viagem1$travel_time/60), col = "red") # linha de média
abline(v = median(duracao_viagem1$travel_time/60), col = "blue") # linha de mediana
round(prop.table(table(duracao_viagem1$transfers))*100, 1) # percentagem de transferências
```
**19%** das paragens são alcançáveis diretamente (**sem transferência de autocarro**).
62% são alcançáveis com 1 transferência no máximo, e 2.6% das paragens necessitam de 5 autocarros para ser alcançadas (4 transferências).
#### Domingo de noite
Filtramos os dados para o próximo Domingo entre as 22h30 e as 23h30, e novamente calculamos a duração da viagem mais rápida entre as paragens de autocarro do Cais do Sodré e todas as outras
```{r}
stop_times_carris2 = filter_stop_times(CARRIS, "2024-11-24", "22:00:00", "23:30:00")
duracao_viagem2 = travel_times(stop_times_carris2, "Cais Sodré", stop_dist_check = FALSE)
nrow(duracao_viagem2)
summary(duracao_viagem2$travel_time/60) # resumo em minutos
```
Num Domingo de noite, é possível alcançar 912 estações da rede (39%) **em menos de** 67 minutos.
#### Visualizar dados num mapa
Podemos criar dois mapas que comparem o tempo que cada paragem demora a alcançar, a partir ddo Cais do Sodré, para os períodos definidos.
Juntamos primeiro os tempos estimados aos dados georreferenciados das estações
```{r}
#| code-fold: true
# hora de ponta
duracao_viagem_CS_HP = ESTACOES_carris |>
left_join(duracao_viagem1, by = c("stop_id" = "to_stop_id")) |> # juntar os dados
filter(transfers >= 1) |> # remover viagens com mais de 1 transferência
filter(!is.na(travel_time)) |> # remover as plataformas não usadas
filter(travel_time < 60*60) |> # remover viagens com mais de 60 minutos
filter(!stop_id %in% c(19001,14601,14602)) # remover as pagarens em Almada
# domingo de noite
duracao_viagem_CS_Dom = ESTACOES_carris |>
left_join(duracao_viagem2, by = c("stop_id" = "to_stop_id")) |> # juntar os dados
filter(transfers >= 1) |> # remover viagens com mais de 1 transferência
filter(!is.na(travel_time)) |> # remover as plataformas não usadas
filter(travel_time < 60*60) |> # remover viagens com mais de 60 minutos
mutate(intervalo = case_when( # criar uma variável com o intervalo de tempo
travel_time < 15*60 ~ "até 15 min",
travel_time < 30*60 ~ "até 30 min",
travel_time < 45*60 ~ "até 45 min",
TRUE ~ "até 60 min" # tudo o resto..
))
```
E "colorimos" o tempo de viagem que demora (*no mínímo*) a alcançar cada estação
```{r}
#| code-fold: true
ggplot(duracao_viagem_CS_HP) +
geom_sf(aes(color = travel_time/60))+
ggtitle("Alcance desde o Cais do Sodré (Carris)",
subtitle = "às 7h30 de Quarta, 20 Nov 2024 - máx 1 transf") +
labs(color = "Tempo de viagem [min]") +
geom_sf(data = LisboaGEO,
fill = "transparent",
color = "grey30") +
theme_bw()
ggplot(duracao_viagem_CS_Dom) +
geom_sf(aes(color = intervalo))+ # mudar para escala discreta
scale_color_manual(values = c("até 15 min" = "#119da4",
"até 30 min" = "#0c7489",
"até 45 min" = "#13505B",
"até 60 min" = "#040404")) +
ggtitle("Alcance desde o Cais do Sodré (Carris)",
subtitle = "às 22h00 de Domingo, 24 Nov 2024 - máx 1 transf") +
labs(color = "Tempo de viagem [min]") +
geom_sf(data = LisboaGEO,
fill = "transparent",
color = "grey30") +
theme_bw()
```
Como podemos visualmnente comparar, em hora de ponta é possível chegar de autocarro a bem mais paragens que num Domingo de noite.
::: callout-tip
#### TPC
Experimente importar, explorar e visualizar os dados GTFS da Carris Metropolitana.
:::
## NeTEX
Outro formato semelhande ao GTFS é o [NeTEX](https://transmodel-cen.eu/index.php/netex/) (Network Timetable EXchange).
Este também é usado por algumas operadoras de TP em Portugal.
{{< video https://youtu.be/KXSI-iRuNfc >}}
O NeTEx está dividido em seis partes, cada uma abrangendo um subconjunto funcional do Transmodelo CEN para Informação sobre Transportes Públicos:
1. Parte 1: Descreve a topologia da rede de transportes públicos (CEN/TS 16614-1:2014)
2. Parte 2: Descreve os horários agendados (CEN/TS 16614-2:2014)
3. Parte 3: Informação tarifária (CEN/TS 16614-3:2015)
4. Parte 4: Perfil Europeu de Informação de Passageiros - EPIP (CEN/TS 16614-4:2017)
5. Parte 5: Formato de intercâmbio de modos alternativos (CEN/TS 16614-5:2021)
6. Parte 6: Perfil Europeu de Acessibilidade às Informações de Passageiros - EPIAP (CEN/TS 16614-6:2024)
Os dados NeTEX usam o formato `.xml`, o que pode tornar a informação mais difícil de ler ou editar.
## GBFS
Para dados de sistemas de mobilidade partilhada e micromobilidade, há ainda o [General Bicycle Feed Specification](https://gbfs.org/) (GBFS).
Tal como os GTFS, os GBFS são dados normalizados com toda a informação sobre os sistemas partilhados, e incluem informações sobre os veículos (bicicletas, trotinetas, motociclos e automóveis), docas, preços, entre outros:
- Localização e disponibilidade de veículos, estações e docas
- Caraterísticas do veículo - tipo de energia, distância que ainda pode ser percorrida
- Preços do serviço e condições de aluguer
- Áreas delimitadas geograficamente para regras relacionadas com velocidade permitida, estacionamento e zonas proibidas
Os dados GBFS são utilizados por aplicações de planeamento de viagens e de Mobilidade como Serviço (MaaS), para fornecer as informações de que os utilizadores necessitam para utilizar a mobilidade partilhada.
As APIs públicas do GBFS facilitam a integração de serviços de mobilidade partilhada com os transportes públicos, permitindo que os utilizadores façam intermodalidade - ligações entre a primeira e a última *milha*.
Além disso, o GBFS fornece aos municípios e operadoras uma forma padronizada de recolher, analisar e comparar dados gerados pelos sistemas de mobilidade partilhada.