-
Notifications
You must be signed in to change notification settings - Fork 23
/
6_cenarios_transporte.qmd
1174 lines (959 loc) · 58.4 KB
/
6_cenarios_transporte.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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Comparando a acessibilidade entre dois cenários de transporte {#sec-6_cenarios_transporte}
Neste capítulo, vamos ilustrar como usar de forma conjunta o material ensinado nos capítulos anteriores para medir o impacto de um projeto de infraestrutura de transporte sobre a acessibilidade urbana. Para avaliar o impacto de projetos de transporte, precisaremos comparar os níveis de acessibilidade antes e depois da implementação do projeto. Para isso, vamos:
1. utilizar diferentes conjuntos de arquivos GTFS e fazer as edições necessárias para representar os cenários antes e depois da implementação do projeto.
2. calcular duas matrizes de tempo de viagem, uma antes e outra depois do investimento.
3. calcular os níveis de acessibilidade, tanto antes quanto depois do investimento; e
4. comparar as condições de acessibilidade em cada cenário, examinando como os impactos se distribuem espacialmente e entre populações de diferentes níveis socioeconômicos.
Vamos cobrir esse passo a passo em detalhes, começando por uma breve apresentação do nosso estudo de caso.
## Apresentação do estudo de caso
Como estudo de caso, vamos fazer uma avaliação do projeto de construção da linha Leste do metrô de Fortaleza (@fig-fortaleza_1). O município de Fortaleza é a capital do estado do Ceará, localizado na região Nordeste do Brasil. Com uma população estimada de 2,7 milhões habitantes, Fortaleza é a quinta cidade mais populosa do país.
```{r}
#| echo: false
#| label: fig-fortaleza_1
#| fig-cap: "Sistema de transporte urbano de média e alta capacidade de Fortaleza. Fonte: @braga2022impactos."
knitr::include_graphics("images/fortaleza_1.png")
```
Um dos grandes investimentos recentes no sistema de transporte de Fortaleza é a linha Leste do metrô. O traçado da linha Leste possui 7,3 km de extensão e liga o centro da cidade ao bairro Papicu, permitindo a integração das linhas de metrô Sul e Oeste com corredores de veículo leve sobre trilhos (VLT) e com o terminal de ônibus no Papicu (@fig-fortaleza_2). Como a linha Leste ainda se encontrava em construção durante a elaboração deste livro, a análise feita neste capítulo trata de uma avaliação *ex-ante*, ou seja, em que avaliamos o futuro impacto de um projeto sobre a acessibilidade urbana. Esse tipo de análise se contrapõe a avaliações *ex-post*, usadas para avaliar o impacto causado por projetos já implementados.
```{r}
#| echo: false
#| label: fig-fortaleza_2
#| fig-cap: "Detalhamento da futura linha Leste do metrô. Fonte: @braga2022impactos."
knitr::include_graphics("images/fortaleza_2.png")
```
::: {.callout-important appearance="simple"}
## O cenário de intervenção analisado
É importante notar que a implementação deste projeto também será acompanhada de mudanças nas frequências das linhas Sul e Oeste do metrô e no corredor de VLT Parangaba-Mucuripe, além do racionamento do sistema de ônibus municipais, conforme o Plano de Acessibilidade Sustentável de Fortaleza (Pasfor)[^pasfor]. Para fins didáticos, no entanto, não incorporamos as mudanças relativas ao racionamento do sistema de ônibus aos cenários da nossa análise. Portanto, o estudo de caso que apresentamos aqui representa um cenário simplificado, que considera apenas a implementação da linha Leste e as mudanças nas frequências das demais linhas do metrô e do VLT[^bragaetal].
:::
[^pasfor]: Disponível em <https://www.pasfor.com.br/>.
[^bragaetal]: Uma avaliação mais completa, que leva em consideração todas as mudanças previstas no Pasfor, pode ser encontrada em @braga2022impactos.
Como mostra a @fig-fortaleza_3, a população de Fortaleza está majoritariamente distribuída na região central e na porção oeste da cidade, embora haja alguns pontos de alta densidade populacional no sudeste da cidade. Via de regra, a população de mais alta renda (em tons de azul no mapa da distribuição de decis de renda) está localizada na região do centro expandido e no sudeste do município, enquanto as populações de menor renda (em tons de vermelho) estão principalmente localizadas nas regiões periféricas ao sul e a oeste. Os empregos formais na cidade se distribuem principalmente ao longo de grandes avenidas, com maior concentração no centro da cidade. Em contraste, as escolas públicas de nível médio têm uma distribuição espacial mais equilibrada por todo o território.
```{r}
#| echo: false
#| results: false
#| warning: false
#| message: false
# cria o endereço de arquivos temporários
end_metrofor <- tempfile("metrofor", fileext = ".zip")
end_linha_leste <- tempfile("linha_leste", fileext = ".zip")
# baixa o gtfs da metrofor
httr::GET(
"https://github.com/ipeaGIT/intro_access_book/releases/download/data_1st_edition/gtfs_for_metrofor_2021-01.zip",
httr::write_disk(end_metrofor)
)
# baixa o gtfs da Linha Leste
httr::GET(
"https://github.com/ipeaGIT/intro_access_book/releases/download/data_1st_edition/gtfs_linha_leste.zip",
httr::write_disk(end_linha_leste)
)
# lê objetos gtfs
gtfs_metrofor <- gtfstools::read_gtfs(end_metrofor)
gtfs_linha_leste <- gtfstools::read_gtfs(end_linha_leste)
# mantém apenas linhas de metrô e de VLT no gtfs da metrofor
gtfs_metrofor <- gtfstools::filter_by_trip_id(
gtfs_metrofor,
trip_id = c("4", "34", "159")
)
# converte corredores para sf
gtfs_metrofor$stop_times <- gtfs_metrofor$stop_times[
order(trip_id, stop_sequence)
]
traj_metrofor <- gtfstools::get_trip_geometry(gtfs_metrofor)
traj_linha_leste <- gtfstools::convert_shapes_to_sf(
gtfs_linha_leste,
shape_id = "LL_0"
)
# renomeia linhas de transporte
traj_linha_leste$shape_id <- "Linha Leste"
traj_metrofor$shape_id <- data.table::fcase(
traj_metrofor$trip_id == 4, "Linha Oeste",
traj_metrofor$trip_id == 34, "Linha Sul",
traj_metrofor$trip_id == 159, "VLT"
)
traj_metrofor$origin_file <- NULL
traj_metrofor$trip_id <- NULL
traj_corredores <- rbind(traj_metrofor, traj_linha_leste)
```
```{r fig_3}
#| echo: false
#| results: false
#| warning: false
#| message: false
#| label: fig-fortaleza_3
#| fig-cap: Distribuição sociodemográfica, de oportunidades de emprego e de educação e de corredores de transporte público em Fortaleza
library(ggplot2)
library(patchwork)
# download dos dados
dados_fortaleza <- aopdata::read_landuse(
city = "Fortaleza",
year = 2019,
showProgress = FALSE,
geometry = TRUE
)
fig_pessoas <- ggplot(data = dados_fortaleza) +
geom_sf(aes(fill = P001), color = NA) +
labs(fill = "Número de\npessoas", color = "Linhas") +
scale_fill_distiller(palette = "PuBu", direction = 1) +
geom_sf(
data = traj_corredores,
mapping = aes(color = shape_id),
alpha = 0.8,
show.legend = FALSE
) +
scale_color_manual(values = c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")) +
theme_void() +
theme(legend.key.size = unit(0.4, "cm"))
fig_renda <- ggplot(data = subset(dados_fortaleza, P001 > 0)) +
geom_sf(aes(fill = as.factor(R003)), color = NA, alpha = 0.8) +
labs(fill = "Decil de\nrenda", color = "Linhas") +
scale_fill_brewer(palette = "RdBu") +
geom_sf(
data = traj_corredores,
mapping = aes(color = shape_id),
alpha = 0.8,
show.legend = FALSE
) +
scale_color_manual(values = c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")) +
theme_void() +
theme(legend.key.size = unit(0.3, "cm"))
fig_empregos <- ggplot(data = dados_fortaleza) +
geom_sf(aes(fill = T001), color = NA) +
labs(fill = "Número de\nempregos") +
scale_fill_distiller(palette = "OrRd", direction = 1) +
geom_sf(
data = traj_corredores,
mapping = aes(color = shape_id),
alpha = 0.8,
show.legend = FALSE
) +
scale_color_manual(values = c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")) +
theme_void() +
theme(legend.key.size = unit(0.4, "cm"))
fig_escolas <- ggplot(data = dados_fortaleza) +
geom_sf(aes(fill = as.factor(E004)), color = NA) +
scale_fill_manual(values = c("grey90", "#66c2a5", "#5e4fa2")) +
labs(fill = "Número de\nescolas", color = "Linhas") +
geom_sf(
data = traj_corredores,
mapping = aes(color = shape_id),
alpha = 0.8
) +
scale_color_manual(values = c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")) +
theme_void() +
theme(legend.key.size = unit(0.4, "cm"))
fig_pessoas + fig_renda + fig_empregos + fig_escolas + plot_layout(ncol = 2)
detach("package:patchwork", unload = TRUE)
detach("package:ggplot2", unload = TRUE)
rm(dados_fortaleza)
rm(list = c("traj_corredores", "traj_linha_leste", "traj_metrofor"))
```
## Dados GTFS usados na análise
Nesta análise, usaremos os arquivos GTFS disponibilizados pela Etufor e pelo Metrofor. Esses dados descrevem o sistema de transporte público operante na cidade de Fortaleza em outubro de 2019. Para ter acesso a esses dados, usamos o código a seguir, que baixa os *feeds* usando o pacote `{httr}`:
```{r}
#| results: false
# cria o endereço de arquivos temporários
end_metrofor <- tempfile("metrofor", fileext = ".zip")
end_etufor <- tempfile("etufor", fileext = ".zip")
# baixa dados da metrofor
httr::GET(
"https://github.com/ipeaGIT/intro_access_book/releases/download/data_1st_edition/gtfs_for_metrofor_2021-01.zip",
httr::write_disk(end_metrofor)
)
# baixa dados da etufor
httr::GET(
"https://github.com/ipeaGIT/intro_access_book/releases/download/data_1st_edition/gtfs_for_etufor_2019-10.zip",
httr::write_disk(end_etufor)
)
```
Para simularmos a implementação da nova linha Leste do metrô, precisamos também de um *feed* que descreva como deverá ser a sua operação. Este *feed* deve conter algumas informações-chave, como, por exemplo, o traçado da linha, a localização de suas estações, o tempo de viagem entre elas e a frequência planejada dos serviços. Neste exemplo, vamos utilizar o arquivo GTFS do projeto da linha Leste criado anteriormente por @braga2022impactos. Assim como os *feeds* da Etufor e do Metrofor, este arquivo está disponível para *download* no repositório do livro no GitHub e pode ser baixado com o código a seguir:
```{r}
#| results: false
# cria o endereço do arquivo temporário
end_linha_leste <- tempfile("linha_leste", fileext = ".zip")
# baixa o GTFS da Linha Leste
httr::GET(
"https://github.com/ipeaGIT/intro_access_book/releases/download/data_1st_edition/gtfs_linha_leste.zip",
httr::write_disk(end_linha_leste)
)
```
Os *feeds* da Etufor e do Metrofor não refletem as mudanças do sistema de transporte público previstas no Pasfor. Para levá-las em consideração no cenário pós-implementação, portanto, precisamos editar esses arquivos usando o pacote `{gtfstools}`.
Em nosso cenário simplificado, vamos considerar as mudanças de frequência no metrô e no VLT relatadas em @braga2022impactos, com base no Pasfor: i) aumento da frequência da linha Sul do metrô de quatro para dez viagens por hora; ii) aumento da frequência da linha Oeste do metrô de duas para cinco viagens por hora; e iii) aumento da frequência do VLT Parangaba-Mucuripe de duas para oito viagens por hora. Como estamos considerando apenas mudanças em linhas de metrô e VLT, vamos nos ater a edições no *feed* do Metrofor. Em primeiro lugar, precisamos ler esse arquivo com a função `read_gtfs()` e entender como as linhas estão descritas. Para isso, vamos olhar como as tabelas `routes`, `trips` e `calendar` estão estruturadas.
```{r}
library(gtfstools)
gtfs_metrofor <- read_gtfs(end_metrofor)
gtfs_metrofor$routes[, .(route_id, route_long_name)]
gtfs_metrofor$trips[, .N, by = .(route_id, direction_id, service_id)]
gtfs_metrofor$calendar
```
O *feed* descreve três linhas distintas: os dois corredores de metrô e o corredor de VLT. Como o *feed* não contém uma tabela `frequencies`, cada rota é descrita por diversas viagens, que partem em diferentes horários do dia. Essas viagens são divididas em viagens de ida e de volta e estão todas associadas a um mesmo serviço, que opera em dias úteis e no sábado.
A estratégia que vamos usar para fazer as mudanças necessárias no *feed* é composta pelas etapas descritas a seguir.
1. Filtrar o *feed* de forma a manter apenas uma viagem por sentido para cada linha, que servirá para nos dizer o tempo que cada viagem leva entre as suas paradas.
2. Adicionar uma tabela `frequencies` ao objeto GTFS, em que descreveremos a frequência de cada viagem.
3. "Converter" os registros da recém-adicionada tabela `frequencies` para cronogramas descritos na tabela `stop_times`. Essa conversão servirá para manter a característica do *feed* original, que descreve as viagens usando apenas a `stop_times`.
Para manter apenas uma viagem por sentido para cada linha, precisamos filtrar o *feed* usando a `filter_by_trip_id()`. Vamos usar a função para manter apenas o primeiro registro de viagem por linha e por sentido.
```{r}
# identifica a linha na tabela trips em que os primeiros registros por rota e
# por sentido estão localizados
indice <- gtfs_metrofor$trips[, .I[1], by = .(route_id, direction_id)]$V1
# seleciona o identificador de cada linha acima
viagens_selecionadas <- gtfs_metrofor$trips[indice]$trip_id
# filtra o gtfs para manter apenas as viagens acima
gtfs_filtrado <- filter_by_trip_id(
gtfs_metrofor,
trip_id = viagens_selecionadas
)
gtfs_filtrado$trips
```
A fim de facilitar nossa edição, vamos mudar o *id* das viagens, identificando o corredor e o sentido em que elas operam. Essa mudança precisa ser feita tanto na tabela `trips` quanto na `stop_times`.
```{r}
gtfs_filtrado$stop_times[
,
trip_id := data.table::fcase(
trip_id == "4", "metro_oeste_0",
trip_id == "19", "metro_oeste_1",
trip_id == "34", "metro_sul_0",
trip_id == "96", "metro_sul_1",
trip_id == "159", "vlt_0",
trip_id == "181", "vlt_1"
)
]
gtfs_filtrado$trips[
,
trip_id := data.table::fcase(
trip_id == "4", "metro_oeste_0",
trip_id == "19", "metro_oeste_1",
trip_id == "34", "metro_sul_0",
trip_id == "96", "metro_sul_1",
trip_id == "159", "vlt_0",
trip_id == "181", "vlt_1"
)
]
gtfs_filtrado$trips
```
Precisamos agora adicionar uma tabela `frequencies` que descreva a frequência de cada viagem. A especificação requer, no entanto, que listemos o *headway* de cada linha, e não a sua frequência. Como o *headway* é o inverso da frequência, precisamos dividir o intervalo de uma hora (3.600 segundos) pela frequência de cada linha (10 viagens/hora para a linha Sul, 5 viagens/hora para a linha Oeste e 8 viagens/hora para o VLT). Como resultado, temos que os *headways* da linha Sul, da linha Oeste e do VLT passarão a ser, respectivamente, 360, 720 e 450 segundos. Com o código a seguir, criamos uma tabela `frequencies` com os pacotes `{tibble}` e `{data.table}`.
```{r}
frequencias <- tibble::tribble(
~trip_id, ~start_time, ~end_time, ~headway_secs, ~exact_times,
"metro_oeste_0", "06:00:00", "09:00:00", 720L, 1,
"metro_oeste_1", "06:00:00", "09:00:00", 720L, 1,
"metro_sul_0", "06:00:00", "09:00:00", 360L, 1,
"metro_sul_1", "06:00:00", "09:00:00", 360L, 1,
"vlt_0", "06:00:00", "09:00:00", 450L, 1,
"vlt_1", "06:00:00", "09:00:00", 450L, 1
)
# converte tabela para data.table
data.table::setDT(frequencias)
# cria tabela frequencies no objeto gtfs com base na tabela acima
gtfs_filtrado$frequencies <- frequencias
```
A fim de simplificar este estudo de caso, assumimos que os *headways* listados são válidos no período de 6h às 9h. Essa premissa é válida no nosso caso, pois iremos calcular as matrizes de tempo de viagem apenas durante o pico da manhã. No entanto, caso desejássemos calcular os tempos de viagens em outros períodos do dia, ou mesmo utilizar este arquivo GTFS na operação do dia a dia desses corredores, precisaríamos listar os *headways* para os demais períodos do dia, como fora-pico, madrugada etc. O valor `1` da coluna `exact_times` estabelece que o cronograma das viagens durante o período especificado deve seguir o *headway* à risca, e não de forma aproximada[^frequencies_chap4].
[^frequencies_chap4]: Para mais detalhes, conferir a descrição da tabela `frequencies` no [Capítulo 4](4_dados_gtfs.qmd#frequencies.txt)).
O objeto GTFS que resulta das modificações feitas até aqui já pode perfeitamente ser utilizado para o cálculo de matrizes de tempo de viagem. Buscando retomar a característica inicial do *feed* de não possuir uma tabela `frequencies`, no entanto, vamos "converter" os registros dessa tabela em cronogramas descritos na tabela `stop_times`. Para isso, usamos a função `frequencies_to_stop_times()`. Como todas as viagens do *feed* são convertidas, a tabela `frequencies` é removida do objeto.
```{r}
gtfs_filtrado <- frequencies_to_stop_times(gtfs_filtrado)
gtfs_filtrado$frequencies
```
Para verificar se a operação deu certo, vamos olhar para as viagens da linha Oeste no sentido Caucaia (cujo `direction_id` é `0`). Como essa linha deve ter uma frequência de cinco viagens por hora entre 6h e 9h, a tabela `trips` deve conter exatamente dezesseis viagens relacionadas a ela (cinco viagens por hora durante três horas, mais uma viagem começando às 9h).
```{r}
# seleciona apenas as viagens da linha oeste do metrô
metro_linha_oeste <- gtfs_filtrado$trips[grepl("metro_oeste_0", trip_id)]
# checa número de viagens
nrow(metro_linha_oeste)
# checa identificador de cada viagem
metro_linha_oeste$trip_id
```
A tabela `stop_times`, por sua vez, deve listar essas viagens partindo a cada doze minutos (o equivalente a um *headway* de 450 segundos). Vamos verificar, portanto, o primeiro registro do cronograma de cada uma das viagens listadas anteriormente.
```{r}
viagens_metro_oeste <- metro_linha_oeste$trip_id
# identifica a linha na tabela stop_times em que estão os primeiros registros de
# cada uma das viagens acima
indice_viagens <- gtfs_filtrado$stop_times[
trip_id %in% viagens_metro_oeste,
.I[1],
by = trip_id
]$V1
gtfs_filtrado$stop_times[indice_viagens, .(trip_id, departure_time)]
```
A operação de "conversão" da tabela `frequencies` para a `stop_times`, portanto, funcionou corretamente, e podemos utilizar o nosso *feed* modificado no cálculo da matriz de tempo de viagem. Para isso, no entanto, precisamos salvar o objeto GTFS na memória em formato `.zip`, assim como estão salvos os demais dados GTFS que serão utilizados no estudo de caso. Para isso, usamos a função `write_gtfs()`.
```{r}
end_metrofor_modificado <- tempfile("metrofor_modificado", fileext = ".zip")
write_gtfs(gtfs_filtrado, end_metrofor_modificado)
```
Temos, agora, quatro arquivos de GTFS distintos:
- o *feed* da Etufor, que descreve o sistema de ônibus que operava em outubro de 2019;
- o *feed* do Metrofor, que descreve a operação em outubro de 2019 das linhas Sul e Oeste do metrô e do VLT Parangaba-Mucuripe;
- o *feed modificado* do Metrofor, que descreve a futura operação das linhas Sul e Oeste do metrô e do VLT Parangaba-Mucuripe como previsto no Pasfor; e
- o *feed* da linha Leste, que descreve a futura operação dessa linha.
Esses quatro arquivos GTFS serão usados em conjunto para calcular as condições de acessibilidade de Fortaleza antes e depois da implementação da linha Leste. No cenário pré-linha Leste, vamos calcular as matrizes de tempo de viagem com base apenas nos *feeds* de outubro de 2019 do Metrofor e da Etufor, que representam a típica operação de transporte público da cidade antes da implementação do novo corredor. No cenário pós-implementação, consideraremos o *feed* da Etufor, o *feed modificado* do Metrofor, com as frequências do metrô e do VLT alteradas, e o arquivo GTFS da linha Leste, incorporando à análise a operação planejada dessa linha após sua finalização.
## Cálculo das matrizes de tempo de viagem
Feitas as edições necessárias ao *feed* do Metrofor e definidos os dados GTFS que vamos usar em cada um dos cenários de transporte público, o próximo passo é calcular as matrizes de tempo de viagem, que posteriormente serão utilizadas para estimar os níveis de acessibilidade. Para isso, vamos utilizar a função `travel_time_matrix()` do pacote `{r5r}`, como apresentado anteriormente no [Capítulo 3](3_calculando_acesso.qmd#sec-matrix).
Antes de calcular as matrizes, contudo, precisamos organizar os nossos arquivos na estrutura que o `{r5r}` requer. Com o código a seguir, criamos uma pasta separada para cada um dos nossos cenários (antes e depois) e salvamos nelas os dados necessários para o roteamento:
```{r}
#| results: false
#| warning: false
# cria pasta raiz da análise de dados
pasta_analise <- "analise_de_impacto"
dir.create(pasta_analise)
# cria pasta dos cenários
pasta_antes <- file.path(pasta_analise, "antes")
pasta_depois <- file.path(pasta_analise, "depois")
dir.create(pasta_antes)
dir.create(pasta_depois)
# copia os arquivos para pasta do cenário "antes"
file.copy(from = end_etufor, to = file.path(pasta_antes, "etufor.zip"))
file.copy(from = end_metrofor, to = file.path(pasta_antes, "metrofor.zip"))
# copia os arquivos para pasta do cenário "depois"
file.copy(from = end_etufor, to = file.path(pasta_depois, "etufor.zip"))
file.copy(
from = end_metrofor_modificado,
to = file.path(pasta_depois, "metrofor_modificado.zip")
)
file.copy(
from = end_linha_leste,
to = file.path(pasta_depois, "linha_leste.zip")
)
# visualiza esquema de arquivos na pasta
fs::dir_tree(pasta_analise)
```
```{r}
#| echo: false
#| results: false
#| warning: false
# a linha abaixo deveria ser suficiente, mas não é por causa de um bug no {fs}:
# https://github.com/r-lib/fs/issues/398
fs::dir_tree(pasta_analise, glob = "*.zip")
# então precisamos mover os arquivos que não devem aparecer na listagem de
# arquivos para uma pasta temporária e então movê-los de volta para a pasta
# original
arquivos_movidos <- c(
"network.dat",
"rede_viaria.osm.pbf.mapdb",
"rede_viaria.osm.pbf.mapdb.p",
"rede_viaria.osm.pbf",
"topografia.tif"
)
antes_tmp <- tempfile("antes")
dir.create(antes_tmp)
file.rename(
file.path(pasta_antes, arquivos_movidos),
file.path(antes_tmp, arquivos_movidos)
)
depois_tmp <- tempfile("depois")
dir.create(depois_tmp)
file.rename(
file.path(pasta_depois, arquivos_movidos),
file.path(depois_tmp, arquivos_movidos)
)
```
```{r}
#| echo: false
fs::dir_tree(pasta_analise)
```
```{r}
#| echo: false
#| results: false
#| warning: false
file.rename(
file.path(antes_tmp, arquivos_movidos),
file.path(pasta_antes, arquivos_movidos)
)
file.rename(
file.path(depois_tmp, arquivos_movidos),
file.path(pasta_depois, arquivos_movidos)
)
```
Para estimarmos o tempo de viagem na nossa área de estudo, precisamos ainda de um arquivo com os dados do OSM representando a rede viária local, em formato `.pbf`. Opcionalmente, iremos utilizar também um arquivo representando a topografia local, em formato `.tif`. Esses arquivos, assim como os dados GTFS, estão disponíveis para *download* no repositório do livro. Partindo do pressuposto de que a implementação da linha Leste não vai afetar o traçado das ruas e calçadas na região, bem como a topografia local, podemos usar os mesmos arquivos para o cálculo das duas matrizes de tempo de viagem. Com o código apresentado a seguir, baixamos esses dados e copiamos os arquivos para as pastas dos dois cenários de transporte:
```{r}
#| results: false
# cria endereço temporário dos arquivos na máquina local
end_pbf <- tempfile("rede_viaria", fileext = ".osm.pbf")
end_tif <- tempfile("topografia", fileext = ".tif")
# download dos dados de OSM
httr::GET(
"https://github.com/ipeaGIT/intro_access_book/releases/download/data_1st_edition/fortaleza.osm.pbf",
httr::write_disk(end_pbf)
)
# download dos dados de topografia
httr::GET(
"https://github.com/ipeaGIT/intro_access_book/releases/download/data_1st_edition/topografia3_for.tif",
httr::write_disk(end_tif)
)
# copia arquivo para as pastas dos cenários antes e depois
file.copy(from = end_pbf, to = file.path(pasta_antes, "rede_viaria.osm.pbf"))
file.copy(from = end_pbf, to = file.path(pasta_depois, "rede_viaria.osm.pbf"))
file.copy(from = end_tif, to = file.path(pasta_antes, "topografia.tif"))
file.copy(from = end_tif, to = file.path(pasta_depois, "topografia.tif"))
```
```{r}
#| echo: false
#| results: false
#| warning: false
arquivos_movidos <- c(
"network.dat",
"rede_viaria.osm.pbf.mapdb",
"rede_viaria.osm.pbf.mapdb.p"
)
file.rename(
file.path(pasta_antes, arquivos_movidos),
file.path(antes_tmp, arquivos_movidos)
)
file.rename(
file.path(pasta_depois, arquivos_movidos),
file.path(depois_tmp, arquivos_movidos)
)
```
```{r}
fs::dir_tree(pasta_analise)
```
```{r}
#| echo: false
#| results: false
#| warning: false
file.rename(
file.path(antes_tmp, arquivos_movidos),
file.path(pasta_antes, arquivos_movidos)
)
file.rename(
file.path(depois_tmp, arquivos_movidos),
file.path(pasta_depois, arquivos_movidos)
)
```
Com os dados organizados nas pastas, podemos começar o cálculo das matrizes de tempo de viagem. A primeira etapa é construir a rede de transporte multimodal usada pelo `{r5r}` no roteamento a partir dos dados da rede viária, do sistema de transporte público e de topografia. Isso é feito com o comando `setup_r5()`, que também retorna uma conexão com o R5. Com o código a seguir, criamos duas redes, uma para cada cenário:
```{r}
#| message: false
#| warning: false
# aloca a memória disponível para o Java
options(java.parameters = "-Xmx4G")
# carrega a biblioteca
library(r5r)
# cria a rede de transporte multimodal de cada cenário
con_r5r_antes <- setup_r5(pasta_antes, verbose = FALSE)
con_r5r_depois <- setup_r5(pasta_depois, verbose = FALSE)
```
Criadas as redes de transporte de cada cenário, prosseguimos para o cálculo das matrizes de tempo de viagem. Nesta etapa, vamos utilizar como origens e destinos os centroides de uma grade espacial de hexágonos de Fortaleza, disponibilizada pelo pacote `{aopdata}`[^aopdata_info]. Cada hexágono tem uma área de 0,11 km², aproximadamente um quarteirão, o que permite uma análise espacial bem detalhada.
[^aopdata_info]: Mais detalhes sobre o pacote são apresentados na [Seção 5](s5_dados_aop.qmd).
Para comparar adequadamente os dois cenários, precisamos calcular as duas matrizes considerando os mesmos parâmetros de viagem. Aqui, vamos considerar viagens a pé ou por transporte público, permitir caminhadas de até trinta minutos nas pernas de acesso e egresso das paradas de transporte público e limitar o tempo máximo de viagem em até sessenta minutos. Vamos considerar o horário de partida de 7h, durante o horário de pico de uma típica segunda-feira de operação:
```{r}
#| message: false
#| warning: false
# baixa os dados da grade espacial
grade_fortaleza <- aopdata::read_grid(city = "Fortaleza")
# calcula os centroides das células da grade
pontos <- sf::st_centroid(grade_fortaleza)
# renomeia o nome da coluna com o id das células
names(pontos)[1] <- "id"
# calcula a matriz de tempo de viagem do cenário "antes"
matriz_antes <- travel_time_matrix(
con_r5r_antes,
origins = pontos,
destinations = pontos,
mode = c("WALK", "TRANSIT"),
departure_datetime = as.POSIXct(
"02-03-2020 07:00:00",
format = "%d-%m-%Y %H:%M:%S"
),
max_walk_time = 30,
max_trip_duration = 60,
verbose = FALSE,
progress = FALSE
)
# calcula a matriz de tempo de viagem do cenário "depois"
matriz_depois <- travel_time_matrix(
con_r5r_depois,
origins = pontos,
destinations = pontos,
mode = c("WALK", "TRANSIT"),
departure_datetime = as.POSIXct(
"02-03-2020 07:00:00",
format = "%d-%m-%Y %H:%M:%S"
),
max_walk_time = 30,
max_trip_duration = 60,
verbose = FALSE,
progress = FALSE
)
head(matriz_antes)
head(matriz_depois)
```
```{r}
#| results: false
#| message: false
#| echo: false
# remove as conexões com o R5
stop_r5()
# libera a memória RAM previamente alocada pro Java
rJava::.jgc()
gc()
```
À primeira vista, nossas matrizes parecem iguais: todos os tempos de viagem na amostra de pares mostrados anteriormente são idênticos. Isso ocorre porque o projeto de expansão do metrô fica restrito a uma área relativamente pequena, no centro da cidade de Fortaleza, e as mudanças nas frequências do VLT e das linhas Sul e Oeste do metrô afetam principalmente as imediações desses corredores. Assim, muitos deslocamentos entre regiões da cidade de fato não são afetados pela implementação do corredor e das mudanças de frequência. Diversos pares origem-destino, no entanto, têm os tempos de viagem entre eles impactados:
```{r}
# une os tempos de viagem dos dois cenários
comparacao <- merge(
matriz_antes,
matriz_depois,
by = c("from_id", "to_id"),
suffixes = c("_antes", "_depois")
)
# mostra apenas os pares OD cujo tempo que os distancia diminuiu
comparacao[travel_time_p50_antes < travel_time_p50_depois]
```
## Cálculo da acessibilidade nos cenários antes e depois
O cálculo dos níveis de acessibilidade nos dois cenários é muito simples, exigindo apenas um processamento básico dos dados e a aplicação de uma das funções de cálculo de acessibilidade do pacote `{accessibility}`. Para facilitar o tratamento dos dados, vamos empilhar as matrizes de tempo de viagem dos dois cenários em uma única tabela, identificando cada cenário com a coluna `cenario`:
```{r}
# combina as matrizes de tempo de viagem dos cenários antes e depois
matriz <- rbind(matriz_antes, matriz_depois, idcol = "cenario")
matriz[, cenario := factor(cenario, labels = c("antes", "depois"))]
matriz
```
Para calcular os níveis de acessibilidade, precisamos de uma tabela com os dados de uso do solo da cidade de Fortaleza. Podemos baixar uma tabela com esses dados usando a função `read_landuse()` do pacote `{aopdata}`, que traz dados de contagem populacional e de oportunidades em cada um dos hexágonos que compõem a grade espacial baixada anteriormente.
```{r}
#| message: false
# baixa dados de uso do solo em fortaleza
dados_fortaleza <- aopdata::read_landuse(
city = "Fortaleza",
showProgress = FALSE
)
```
A fins de demonstração, vamos calcular a acessibilidade a postos de trabalho e a escolas públicas de ensino médio na nossa área de estudo. Os dados do total de empregos e de escolas públicas de nível médio em cada hexágono estão listados nas colunas `T001` e `E004`, respectivamente. Vamos renomeá-las para facilitar sua identificação e manter apenas as colunas necessárias na tabela de dados de uso do solo. Vamos manter também as colunas `P001`, de população total em cada hexágono, e `R003`, do decil de renda em que cada hexágono se encontra, que serão úteis mais à frente:
```{r}
# renomeia colunas
colunas_mantidas <- c("id", "empregos", "escolas", "populacao", "decil")
data.table::setnames(
dados_fortaleza,
old = c("id_hex", "T001", "E004", "P001", "R003"),
new = colunas_mantidas
)
# deleta as demais colunas que não serão usadas
dados_fortaleza[, setdiff(names(dados_fortaleza), colunas_mantidas) := NULL]
dados_fortaleza
```
Uma decisão-chave no cálculo de acessibilidade é a escolha da medida a ser utilizada. É extremamente importante pesar as vantagens e desvantagens de cada medida e compreender quais indicadores se adequam às oportunidades para as quais desejamos calcular os níveis de acessibilidade. Neste exemplo, utilizaremos duas medidas distintas:
1. No cálculo da acessibilidade a empregos, vamos usar a medida de oportunidades cumulativas. Essa métrica nos permite entender quantos empregos são acessíveis dentro de um determinado custo de viagem. Apesar das suas limitações discutidas no [Capítulo 2](2_indicadores.qmd#medida-de-oportunidades-cumulativas), este é um dos indicadores mais amplamente utilizados. Isso se deve, em grande medida, à facilidade de comunicar e interpretar seus resultados. Nesse exemplo, vamos estabelecer como limite de custo um tempo de viagem de sessenta minutos, valor muito próximo do tempo médio de deslocamento casa-trabalho por transporte público de Fortaleza em 2019 (cerca de 58 minutos, segundo o Pasfor).
2. No cálculo da acessibilidade a escolas públicas, vamos usar a medida de custo mínimo de viagem. Essa métrica é especialmente útil para avaliar a cobertura de serviços públicos essenciais, como educação e saúde básica. Com ela, podemos, por exemplo, identificar as parcelas da população que estão a uma distância maior do que a considerada razoável para acessar esses serviços essenciais.
Como mostrado anteriormente no [Capítulo 3](3_calculando_acesso.qmd#sec-accessibility), o cálculo dessas medidas pode ser feito com as funções `cumulative_cutoff()` e `cost_to_closest()`, respectivamente, do pacote `{accessibility}`:
```{r}
# carrega a biblioteca
library(accessibility)
# calcula a medida de oportunidades cumulativas
acesso_a_empregos <- cumulative_cutoff(
matriz,
land_use_data = dados_fortaleza,
opportunity = "empregos",
travel_cost = "travel_time_p50",
cutoff = 60,
group_by = "cenario"
)
acesso_a_empregos
# calcula a medida de tempo mínimo de viagem
tempo_a_escolas <- cost_to_closest(
matriz,
land_use_data = dados_fortaleza,
opportunity = "escolas",
travel_cost = "travel_time_p50",
group_by = "cenario"
)
tempo_a_escolas
```
O resultado da função de custo mínimo de viagem inclui alguns valores `Inf` (abreviação de infinito). Esse valor é utilizado para sinalizar origens que não conseguem alcançar nenhuma oportunidade, dadas as viagens que compõem a matriz. Em nosso caso, isso significa que as origens listadas com esse valor não conseguem alcançar nenhuma escola pública de nível médio dentro de sessenta minutos (limite de tempo de viagem imposto no cálculo da matriz). Para simplificar os cálculos daqui em diante, vamos considerar que essas regiões estão a oitenta minutos de viagem de sua escola mais próxima:
```{r}
# substitui valores Inf por tempos de viagem de 80 minutos
tempo_a_escolas[
,
travel_time_p50 := ifelse(is.infinite(travel_time_p50), 80, travel_time_p50)
]
```
Feito isso, podemos calcular a diferença dos níveis de acessibilidade entre os dois cenários. Esta informação é útil para comunicar de forma mais direta o efeito da implementação da linha Leste e das mudanças de frequência dos outros corredores sobre as condições de acessibilidade na cidade. Para isso, usamos o código adiante:
```{r}
acesso_a_empregos[
,
diferenca := data.table::shift(empregos, type = "lead") - empregos,
by = id
]
tempo_a_escolas[
,
diferenca := data.table::shift(travel_time_p50, type = "lead") -
travel_time_p50,
by = id
]
```
## Análise dos níveis de acessibilidade antes e depois
Agora que calculamos os níveis de acessibilidade em cada cenário e a diferença entre eles, nós conseguimos analisar como a futura implementação da linha Leste em conjunto com o aumento da frequência das linhas de metrô e VLT deverá impactar as condições de acessibilidade em nossa área de estudo. Como primeira análise exploratória, podemos investigar o impacto dessas mudanças sobre a acessibilidade média da cidade. Olhando primeiro para a acessibilidade a oportunidades de emprego, vamos calcular a quantidade média de empregos acessíveis em cada cenário. Aqui, é importante calcular a média de acessibilidade ponderada pela população de cada célula da grade espacial que estamos usando, visto que células com maiores populações contribuem mais para o nível médio da população como um todo do que células com poucas pessoas.
```{r fig_4}
#| label: fig-fig_4
#| fig-cap: Média de acessibilidade ao emprego em Fortaleza por cenário de transporte
# carrega bibliotecas de visualização de dados
library(ggplot2)
library(patchwork)
# une tabela de acessibilidade com informações de pessoas residentes e renda em
# renda nos hexágonos
acesso_a_empregos <- merge(
acesso_a_empregos,
dados_fortaleza,
by = "id"
)
# renomeia colunas com nomes ambíguos pós-união
data.table::setnames(
acesso_a_empregos,
old = c("empregos.x", "empregos.y"),
new = c("acesso_a_empregos", "empregos_no_hexagono")
)
# calcula a média ponderada de acessibilidade em cada cenário
acesso_medio <- acesso_a_empregos[
,
.(acesso = weighted.mean(acesso_a_empregos, w = as.numeric(populacao))),
by = cenario
]
ggplot(data = acesso_medio, aes(x = cenario, y = acesso / 1000)) +
geom_col(fill = "#0f3c53") +
geom_text(
aes(
label = formatC(
acesso / 1000,
digits = 1,
decimal.mark = ",",
format = "f"
)
),
vjust = 1.5,
color = "white",
size = 10
) +
ylab("Empregos acessíveis (em milhares)") +
scale_x_discrete(name = "Cenário", labels = c("Antes", "Depois")) +
theme_minimal()
```
```{r}
#| echo: false
acesso_antes <- round(acesso_medio[cenario == "antes"]$acesso)
acesso_antes_string <- formatC(
acesso_antes,
big.mark = ".",
format = "f",
digits = 0,
decimal.mark = ","
)
acesso_depois <- round(acesso_medio[cenario == "depois"]$acesso)
acesso_depois_string <- formatC(
acesso_depois,
big.mark = ".",
format = "f",
digits = 0,
decimal.mark = ","
)
aumento <- (acesso_depois - acesso_antes) / acesso_antes
aumento_string <- formatC(
aumento * 100,
format = "f",
digits = 1,
decimal.mark = ","
)
```
Os resultados mostram que a população de Fortaleza conseguia acessar em média `r acesso_antes_string` empregos em até sessenta minutos de viagem por transporte público antes da expansão do metrô, em 2019. A implementação da linha Leste e os aumentos nas frequências do metrô e do VLT aumentam esse valor em `r aumento_string`%, para `r acesso_depois_string` empregos em média.
Analisando o tempo médio de acesso à escola pública de ensino médio mais próxima, notamos que as mudanças no sistema de transportes pouco alteram a acessibilidade a essas escolas. Em média, a população de Fortaleza demorava cerca de 12 minutos e meio para chegar à escola pública de ensino médio mais próxima de sua casa em 2019. Após a conclusão da extensão do metrô e o aumento da frequência das linhas de metrô e VLT, esse resultado permanece praticamente inalterado.
```{r fig_5}
#| label: fig-fig_5
#| fig-cap: Média do tempo até a escola pública de nível médio mais próxima em Fortaleza por cenário de transporte
# une tabela de tempo a escolas com informações de pessoas residentes nos
# hexágonos
tempo_a_escolas <- merge(
tempo_a_escolas,
dados_fortaleza,
by = "id"
)
# calcula a média ponderada de acessibilidade em cada cenário
tempo_medio <- tempo_a_escolas[
,
.(tempo = weighted.mean(travel_time_p50, w = as.numeric(populacao))),
by = cenario
]
ggplot(data = tempo_medio, aes(x = cenario, y = tempo)) +
geom_col(fill = "#0d6556") +
geom_text(
aes(label = formatC(tempo, digits = 2, decimal.mark = ",", format = "f")),
vjust = 1.5,
color = "white",
size = 10
) +
ylab("Média do tempo até a escola\nmais próxima (minutos)") +
scale_x_discrete(name = "Cenário", labels = c("Antes", "Depois")) +
theme_minimal()
```
Em síntese, os resultados mostram que o plano de construção da Linha Leste do metrô e de ajuste das frequências de outros corredores de transporte público da cidade deverá afetar mais significativamente a acessibilidade a oportunidades de emprego do que a acessibilidade a escolas públicas de nível médio. Isso se explica principalmente pela distribuição espacial desses dois tipos de oportunidade na cidade de Fortaleza: enquanto os empregos se distribuem de forma muito mais concentrada no centro da cidade, as escolas estão muito mais bem distribuídas em todo o território. As mudanças no sistema de transporte público, portanto, devem facilitar o acesso de moradores de regiões mais afastadas aos empregos localizados no centro. Em contrapartida, a distribuição mais equitativa de escolas públicas resulta em condições relativamente boas de acesso a esses locais mesmo antes das mudanças na rede de transporte, explicando por que tais mudanças deverão ter impacto tão pequeno no tempo médio de acesso a escolas.
Esses resultados podem ser melhor compreendidos quando observamos a sua distribuição espacial. Antes de fazer isso, no entanto, vamos criar um objeto espacial que descreve o traçado dos corredores de transporte da cidade - o que torna ainda mais evidente o impacto das mudanças no sistema de transportes sobre os níveis de acessibilidade.
```{r fig_6}
#| label: fig-fig_6
#| fig-cap: Distribuição dos corredores de transporte de média e alta capacidade em Fortaleza por cenário de transporte
# lê arquivos gtfs necessários para gerar as geometrias de cada corredor
gtfs_metrofor <- read_gtfs(end_metrofor)
gtfs_linha_leste <- read_gtfs(end_linha_leste)
# gtfs da metrofor não contém tabela shapes, logo vamos criar a geometria
# a partir das tabelas stops e stop_times com a função get_trip_geometry()
viagens_corredores <- c("4", "34", "159")
# a sequência de paradas de uma das viagens não está ordenada corretamente,
# então precisamos ordená-las manualmente
gtfs_metrofor$stop_times <- gtfs_metrofor$stop_times[
order(trip_id, stop_sequence)
]
traj_metrofor <- gtfstools::get_trip_geometry(
gtfs_metrofor,
trip_id = viagens_corredores
)
# converte o trajeto em um dos sentidos da linha leste em geometria espacial
traj_linha_leste <- gtfstools::convert_shapes_to_sf(
gtfs_linha_leste,
shape_id = "LL_0"
)
# nomeia cada uma das linhas e une as tabelas
traj_linha_leste$corredor <- "Linha Leste"
traj_metrofor$corredor <- data.table::fcase(
traj_metrofor$trip_id == 4, "Linha Oeste",
traj_metrofor$trip_id == 34, "Linha Sul",
traj_metrofor$trip_id == 159, "VLT"
)
traj_metrofor$origin_file <- NULL
traj_metrofor$trip_id <- NULL
traj_linha_leste$shape_id <- NULL
traj_corredores <- rbind(traj_metrofor, traj_linha_leste)
# duplica a tabela, adiciona coluna identificando cada cenário e remove a linha
# leste do cenário pré-implementação das mudanças
traj_corredores <- rbind(traj_corredores, traj_corredores)
traj_corredores$cenario <- rep(c("antes", "depois"), each = 4)
traj_corredores <- subset(
traj_corredores,
corredor != "Linha Leste" | cenario != "antes"
)
ggplot() +
geom_sf(data = grade_fortaleza, fill = "gray90", color = NA) +
geom_sf(data = traj_corredores, aes(color = corredor)) +
scale_color_manual(
name = "Corredor",
values = c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")
) +
facet_wrap(
~ cenario,
nrow = 1,
labeller = as_labeller(c(antes = "Antes", depois = "Depois"))
) +
theme_void()
```
Podemos, então, analisar a distribuição espacial dos níveis de acessibilidade nos cenários antes e depois, bem como a diferença de acessibilidade entre eles. Para isso, temos que juntar as estimativas de acessibilidade com a grade espacial da nossa área de estudo. Primeiro, para a acessibilidade a empregos, como mostrado a seguir.
```{r fig_7}
#| label: fig-fig_7
#| fig-cap: Distribuição espacial dos níveis de acessibilidade ao emprego por cenário de transporte e da diferença entre eles
# une os dados de acessibilidade com a grade espacial de fortaleza e os converte
# em objetos espaciais
acesso_a_empregos <- merge(
acesso_a_empregos,
grade_fortaleza,
by.x = "id",
by.y = "id_hex"
)
acesso_a_empregos_sf <- sf::st_sf(acesso_a_empregos)
# configura mapas da distribuição de acessibilidade nos cenários antes e depois
dist_acesso <- ggplot() +
geom_sf(
data = acesso_a_empregos_sf,
aes(fill = acesso_a_empregos),
color = NA
) +
facet_wrap(
~ cenario,
nrow = 1,
labeller = as_labeller(c(antes = "Antes", depois = "Depois"))
) +
scale_fill_viridis_c(
option = "inferno",
label = scales::label_number(scale = 1 / 1000)
) +
labs(fill = "Empregos\nacessíveis\n(em milhares)", color = "Corredores") +
geom_sf(
data = traj_corredores,
aes(color = corredor),
alpha = 0.8,
show.legend = FALSE
) +
scale_color_manual(values = c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")) +
theme_void() +
theme(legend.key.size = unit(0.4, "cm"))
# configura mapa de diferença entre cenários
dist_diferenca <- ggplot() +
geom_sf(
data = subset(acesso_a_empregos_sf, !is.na(diferenca)),
aes(fill = diferenca),
color = NA
) +
scale_fill_viridis_c(
option = "cividis",
label = scales::label_number(scale = 1 / 1000)
) +
labs(
fill = "Diferença de\nempregos\nacessíveis\n(em milhares)",
color="Corredores"
) +
geom_sf(data = traj_corredores, aes(color = corredor), alpha = 0.8) +
scale_color_manual(values = c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")) +
theme_void() +
theme(legend.key.size = unit(0.4, "cm"))
# combina as duas figuras
dist_acesso / dist_diferenca + plot_layout(ncol = 1, heights = c(1, 1))
```
A @fig-fig_7 mostra que as regiões que mais se beneficiam das mudanças no sistema de transportes são aquelas afastadas do centro da cidade, mas que ainda se encontram próximas a estações de média e alta capacidade. Os ganhos de acessibilidade ao emprego se concentram principalmente próximos às estações dos corredores das linhas Sul e Oeste do metrô e, em menor medida, em torno de algumas estações do corredor de VLT Parangaba-Mucuripe. Mesmo regiões próximas a esses corredores, embora não imediatamente adjacentes a eles, mostram grandes ganhos de acessibilidade, ressaltando o papel da conectividade da rede na garantia de boas condições de acessibilidade. Por sua vez, a região no entorno da linha Leste, que já concentrava os maiores níveis de acessibilidade da cidade mesmo antes da implementação do novo corredor, apresenta melhora nas condições de acessibilidade muito menos expressiva.
Os mapas de distribuição do tempo de acesso até a escola de nível médio mais próxima, no entanto, apresentam uma situação diferente, como mostrado a seguir.
```{r fig_8}
#| label: fig-fig_8
#| fig-cap: Distribuição espacial dos tempos de acesso à escola pública de nível médio mais próxima por cenário de transporte e da diferença entre eles
# une os dados de tempo de acesso com a grade espacial de fortaleza e os
# converte em objetos espaciais
tempo_a_escolas <- merge(
tempo_a_escolas,
grade_fortaleza,
by.x = "id",
by.y = "id_hex"
)
tempo_a_escolas_sf <- sf::st_sf(tempo_a_escolas)