Pease clone repository or download data from https://github.com/U-Shift/shinytrips-aml/tree/master/data
MUNICIPIOSgeo.Rds
: geometries of municipalities in Lisbon Metropolitan Area (AML), as polygons
TRIPSmodemunicipio.Rds
: matrix of trips between municipalities, and separated by transportation mode, in long-format
MUNICIPIOSgeo = readRDS("data/MUNICIPIOSgeo.Rds")
TRIPS = readRDS("data/TRIPSmodemunicipio.Rds")
You will need to get the centroids (center of mass) from the municipal geometries. There are two types of centroids: the geometric ones and the population or workplace weighted ones.
To calculate geometric centroids:
library(sf)
CENTROIDSgeo = st_centroid(MUNICIPIOSgeo)
library(mapview)
mapviewOptions(fgb = FALSE)
mapview(MUNICIPIOSgeo) + mapview(CENTROIDSgeo, col.regions = "black", legend = F)
How to calculate population weighted centroids, also known as mean coordinates?
Tip:
- use Census 2011 database, at any smaller level than municipalities, and its population data.
- check QGIS> Vector > Analysis Tools > Mean Coordinates. The ID should be the municipality.
There are several routing softwares that can do this process. We will guide you through a free and opensource one, based on OpenStreetMap road network: openroute service.
First you will need to sign up and register for an API key (token).
If you are familiar with QGIS, you can use the plugin ORS tools, which might be more intuitive for the following operations.
At settings, add your API Key. Batch Jobs > Matrix.
In this case we will use driving-car
as the transportation mode.
You will get a matrix with the travel time (hours) and travel distance (km) between each centroid, that you can export in any format you’d like.
Keep in mind that your API key have a maximum number of requests per day and per minute.
This will not retrieve the routes (polylines) that were considered. If you need those, you’ll have to use other process: Batch Jobs > Points (2 Layers) > All-by-All.
You will need to install the openrouteservice-r
package. See vignette for more information.
# remotes::install_github("GIScience/openrouteservice-r")
library(openrouteservice)
# ors_api_key("<your-api-key>")
# ors_api_key(Sys.getenv("ORS_API_KEY")) #if you have it stotred in usethis::edit_r_environ()
CENTROIDSgeo$coordinates = st_coordinates(CENTROIDSgeo) #list of xy coordinates
# compute time and distance, with routing profile
TRIPSmatrix = ors_matrix(
CENTROIDSgeo$coordinates,
profile = "driving-car",
metrics = c("duration", "distance"),
units = "km"
)
TRIPSmatrix_dist = as.data.frame(TRIPSmatrix[["distances"]])
TRIPSmatrix_time = as.data.frame(TRIPSmatrix[["durations"]])
TRIPSmatrix_time = TRIPSmatrix_time/60 #in minutes
# row and colunm names
MUNICIPALITIES = CENTROIDSgeo$Concelho
colnames(TRIPSmatrix_dist) = MUNICIPALITIES
rownames(TRIPSmatrix_dist) = MUNICIPALITIES
colnames(TRIPSmatrix_time) = MUNICIPALITIES
rownames(TRIPSmatrix_time) = MUNICIPALITIES
This will give you a matrix in wide format as this:
Alcochete | Almada | Amadora | Barreiro | Cascais | Lisboa | Loures | Mafra | Moita | Montijo | Odivelas | Oeiras | Palmela | Seixal | Sesimbra | Setubal | Sintra | Vila Franca de Xira | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Alcochete | 0.00 | 40.07 | 36.49 | 24.77 | 60.65 | 34.89 | 34.22 | 58.22 | 17.25 | 26.45 | 33.53 | 47.16 | 28.78 | 31.99 | 39.10 | 33.98 | 53.13 | 36.22 |
Almada | 39.60 | 0.00 | 22.18 | 20.81 | 38.39 | 16.71 | 36.72 | 60.71 | 27.25 | 59.34 | 27.45 | 24.90 | 42.47 | 10.98 | 23.15 | 41.49 | 40.86 | 71.00 |
Amadora | 37.87 | 22.41 | 0.00 | 41.32 | 27.12 | 8.62 | 18.16 | 42.16 | 43.38 | 59.50 | 8.89 | 9.21 | 57.88 | 25.19 | 38.85 | 59.80 | 19.57 | 51.76 |
Barreiro | 25.81 | 21.34 | 33.79 | 0.00 | 50.00 | 28.32 | 49.87 | 73.87 | 6.99 | 45.54 | 49.19 | 36.51 | 30.84 | 13.26 | 19.27 | 29.86 | 52.47 | 57.21 |
Cascais | 58.29 | 34.30 | 24.13 | 53.20 | 0.00 | 25.46 | 39.95 | 42.52 | 56.56 | 79.92 | 34.80 | 14.72 | 68.30 | 37.08 | 50.74 | 67.31 | 18.30 | 72.59 |
Lisboa | 35.39 | 18.54 | 8.26 | 37.45 | 30.16 | 0.00 | 20.89 | 44.89 | 40.90 | 57.03 | 11.62 | 16.67 | 52.54 | 21.32 | 34.98 | 51.56 | 26.71 | 45.82 |
Loures | 36.08 | 33.39 | 18.34 | 49.12 | 43.21 | 18.11 | 0.00 | 31.22 | 41.59 | 57.72 | 15.39 | 29.60 | 56.10 | 36.16 | 49.83 | 58.02 | 33.08 | 40.33 |
Mafra | 60.10 | 57.40 | 42.36 | 73.14 | 38.82 | 42.12 | 31.89 | 0.00 | 65.61 | 81.73 | 35.29 | 47.88 | 80.11 | 60.18 | 73.84 | 82.04 | 25.51 | 66.49 |
Moita | 17.84 | 28.63 | 44.18 | 7.00 | 61.11 | 39.43 | 41.91 | 65.91 | 0.00 | 37.58 | 41.22 | 47.62 | 21.09 | 20.55 | 27.66 | 24.12 | 60.82 | 49.24 |
Montijo | 26.34 | 59.73 | 61.46 | 44.44 | 85.61 | 59.85 | 59.19 | 83.18 | 36.91 | 0.00 | 58.50 | 72.12 | 22.98 | 51.65 | 58.77 | 48.53 | 78.10 | 44.07 |
Odivelas | 34.83 | 27.38 | 8.11 | 47.87 | 32.27 | 12.10 | 15.12 | 36.03 | 40.34 | 56.47 | 0.00 | 18.78 | 54.85 | 30.15 | 43.82 | 56.77 | 24.39 | 49.43 |
Oeiras | 48.40 | 24.41 | 10.31 | 43.32 | 16.24 | 15.58 | 29.96 | 49.19 | 46.68 | 70.04 | 24.81 | 0.00 | 58.41 | 27.19 | 40.85 | 57.42 | 19.36 | 62.60 |
Palmela | 32.36 | 43.95 | 66.90 | 30.81 | 72.65 | 50.97 | 64.63 | 88.63 | 21.15 | 22.97 | 63.94 | 59.16 | 0.00 | 33.31 | 40.17 | 18.44 | 75.12 | 63.76 |
Seixal | 31.61 | 11.57 | 25.51 | 12.82 | 41.72 | 20.04 | 40.05 | 64.04 | 19.26 | 51.35 | 30.78 | 28.23 | 32.32 | 0.00 | 14.12 | 31.34 | 44.19 | 63.01 |
Sesimbra | 38.65 | 23.88 | 39.14 | 19.25 | 55.35 | 33.67 | 53.68 | 77.67 | 26.30 | 58.39 | 44.41 | 41.86 | 45.58 | 14.08 | 0.00 | 31.52 | 57.82 | 70.05 |
Setubal | 33.05 | 43.89 | 59.51 | 30.28 | 72.12 | 50.44 | 57.24 | 81.23 | 23.87 | 55.17 | 56.55 | 58.63 | 18.08 | 32.78 | 30.98 | 0.00 | 76.15 | 64.46 |
Sintra | 54.64 | 40.27 | 21.11 | 59.17 | 15.08 | 26.77 | 32.85 | 24.27 | 60.16 | 76.28 | 27.70 | 20.33 | 74.26 | 43.04 | 56.71 | 76.58 | 0.00 | 65.49 |
Vila Franca de Xira | 35.45 | 71.38 | 48.73 | 56.09 | 72.41 | 47.13 | 37.61 | 62.79 | 48.56 | 47.28 | 46.21 | 58.80 | 60.10 | 63.30 | 70.42 | 65.29 | 62.28 | 0.00 |
You also can put it back to long format as:
TRIPSmatrix_dist$Origin = rownames(TRIPSmatrix_dist)
TRIPSmatrix_time$Origin = rownames(TRIPSmatrix_time)
library(tidyr)
TRIPSdist = pivot_longer(
TRIPSmatrix_dist,
cols = !Origin,
names_to = "Destination",
values_to = "Distance"
)
TRIPStime = pivot_longer(
TRIPSmatrix_time,
cols = !Origin,
names_to = "Destination",
values_to = "Time"
)
And then use left_join
to join distance and time values to the original TRIPS table.
Origin | Destination | Distance | Time |
---|---|---|---|
Alcochete | Alcochete | 0.00 | 0.00 |
Alcochete | Almada | 40.07 | 31.06 |
Alcochete | Amadora | 36.49 | 29.25 |
Alcochete | Barreiro | 24.77 | 21.44 |
Alcochete | Cascais | 60.65 | 43.92 |
Alcochete | Lisboa | 34.89 | 29.55 |
Alcochete | Loures | 34.22 | 29.34 |
Alcochete | Mafra | 58.22 | 48.40 |
Alcochete | Moita | 17.25 | 18.40 |
Alcochete | Montijo | 26.45 | 29.94 |
Alcochete | Odivelas | 33.53 | 29.65 |
Alcochete | Oeiras | 47.16 | 36.92 |
Alcochete | Palmela | 28.78 | 36.23 |
Alcochete | Seixal | 31.99 | 24.27 |
Alcochete | Sesimbra | 39.10 | 37.40 |
Alcochete | Setubal | 33.98 | 31.28 |
Alcochete | Sintra | 53.13 | 40.55 |
Alcochete | Vila Franca de Xira | 36.22 | 52.33 |
Almada | Alcochete | 39.60 | 28.67 |
Almada | Almada | 0.00 | 0.00 |
Easy, right? 😉