# Hello, MATSim world!
#
# You can learn more about package authoring with RStudio at:
#
# http://r-pkgs.had.co.nz/
#
# Some useful keyboard shortcuts for package authoring:
#
# Install Package: 'Cmd + Shift + B'
# Check Package: 'Cmd + Shift + E'
# Test Package: 'Cmd + Shift + T'
# -----------------------------------------------------------
#' @import dplyr
#' @import readr
#' @import purrr
#' @import xml2
#' @import sf
#' @import ggalluvial
#' @import ggrepel
#' @import tidyverse
#' @rawNamespace import(tidyr, except = expand)
#' @rawNamespace import(ggplot2, except = last_plot)
#' @import yaml
#' @import plotly
#' @import leaflet
#' @import forcats
#' @import lubridate
#' @import htmltools
#' @rawNamespace import(reshape, except = c(stamp,rename,expand))
# NETWORK = "kelheim.output_network.xml"
# NETWORK = "network.xml"
NETWORK <- "berlin.network.xml.gz"
# prevent warning about global use of "name". Thanks dplyr
utils::globalVariables(c("name"))
# ------
#' Load MATSim network into memory
#'
#' Loads a MATSim XML network file, creating a nodes tibble and a links tibble.
#' Any node and link attribute records in the network are stored as
#' additional columns in the respective node and link tibbles.
#'
#' The links table is automatically joined with the nodes table so that
#' node x/y coordinates (and any other node attributes) are available in the
#' links table without additional processing.
#'
#' @param filename File to load. Can be XML or gzipped XML
#'
#' @return "nodes" and "links" tibbles in a list object.
#'
#' @export
read_network <- function(filename) {
cat(filename, ": ")
network <- read_xml(filename)
cat("Nodes..")
node_elements <- network %>% xml_find_all("./nodes/node")
nodes <- tibble(
id = node_elements %>% xml_attr("id"),
x = node_elements %>% xml_attr("x") %>% parse_double(),
y = node_elements %>% xml_attr("y") %>% parse_double(),
)
attributes <- node_elements %>% xml_find_all("./attributes/attribute")
# skip if there are no node attributes
if (length(attributes)) {
attrIds <- tibble(id = unlist(map(attributes, function(row) xml_attr(xml_parent(xml_parent(row)), "id"))))
nodeAttributes <- tibble(
id = attrIds$id,
name = attributes %>% xml_attr("name"),
class = attributes %>% xml_attr("class"),
value = attributes %>% xml_text(),
)
# which columns should be converted to numeric?
types <- nodeAttributes %>%
select(name, class) %>%
distinct()
convert <- filter(types, class == "java.lang.Double")$name
# convert to a format we can join to the links
nodeAttributes <- (nodeAttributes
%>% select(-class)
%>% pivot_wider(names_from = "name", values_from = "value")
%>% mutate_at(vars(one_of(convert)), as.double)
)
nodes <- nodes %>% left_join(nodeAttributes, by = "id")
}
cat("Links..")
link_elements <- network %>% xml_find_all("./links/link")
links <- tibble(
id = link_elements %>% xml_attr("id"),
from = link_elements %>% xml_attr("from"),
to = link_elements %>% xml_attr("to"),
length = link_elements %>% xml_attr("length") %>% parse_double(),
freespeed = link_elements %>% xml_attr("freespeed") %>% parse_double(),
capacity = link_elements %>% xml_attr("capacity") %>% parse_double(),
permlanes = link_elements %>% xml_attr("permlanes") %>% parse_double(),
modes = link_elements %>% xml_attr("modes"),
origid = link_elements %>% xml_attr("origid")
)
# merge node coordinates
links <- (links
%>% left_join(nodes, by = c("from" = "id"))
%>% left_join(nodes, by = c("to" = "id"), suffix = c(".from", ".to"))
)
# attributes don't have IDs on them! JFC, MATSim!
cat("Attributes..")
attributes <- link_elements %>% xml_find_all("./attributes/attribute")
# skip if there are no link-attributes
if (length(attributes)) {
attrIds <- tibble(id = unlist(map(attributes, function(row) xml_attr(xml_parent(xml_parent(row)), "id"))))
linkAttributes <- tibble(
id = attrIds$id,
name = attributes %>% xml_attr("name"),
class = attributes %>% xml_attr("class"),
value = attributes %>% xml_text(),
)
# which columns should be converted to numeric?
types <- linkAttributes %>%
select(name, class) %>%
distinct()
convert <- filter(types, class == "java.lang.Double")$name
# convert to a format we can join to the links
linkAttributes <- (linkAttributes
%>% select(-class)
%>% pivot_wider(names_from = "name", values_from = "value")
%>% mutate_at(vars(one_of(convert)), as.double)
)
links <- links %>% left_join(linkAttributes, by = "id", suffix = c(".link", ".attr"))
}
# Top-level network attributes
networkAttributes <- NULL
allNetworkAttributes <- network %>% xml_find_all("./attributes/attribute")
if (length(allNetworkAttributes)) {
networkAttributes <- tibble(
name = allNetworkAttributes %>% xml_attr("name"),
class = allNetworkAttributes %>% xml_attr("class"),
value = allNetworkAttributes %>% xml_text(),
)
# which columns should be converted to numeric?
types <- networkAttributes %>%
select(name, class) %>%
distinct()
convert <- filter(types, class == "java.lang.Double")$name
# convert to a format we can join to the links
networkAttributes <- (networkAttributes
%>% select(-class)
%>% pivot_wider(names_from = "name", values_from = "value")
%>% mutate_at(vars(one_of(convert)), as.double)
)
}
cat("Done!\n")
list("nodes" = nodes, "links" = links, "attributes" = networkAttributes)
}
#' Load MATSim network into memory
#'
#' \strong{loadNetwork} - Loads a MATSim XML network file, creating a nodes tibble and a links tibble.
#' Any node and link attribute records in the network are stored as
#' additional columns in the respective node and link tibbles.\cr
#' The links table is automatically joined with the nodes table so that
#' node x/y coordinates (and any other node attributes) are available on the
#' links table without additional processing.
#'
#' @rdname matsimr-deprecated
#'
#' @param filename File to load. Can be XML or gzipped XML
#'
#' @return \strong{loadNetwork} - "nodes" and "links" tibbles in a list object.
#'
loadNetwork <- function(filename) {
.Deprecated("read_network")
cat(filename, ": ")
network <- read_xml(filename)
cat("Nodes..")
node_elements <- network %>% xml_find_all("./nodes/node")
nodes <- tibble(
id = node_elements %>% xml_attr("id"),
x = node_elements %>% xml_attr("x") %>% parse_double(),
y = node_elements %>% xml_attr("y") %>% parse_double(),
)
attributes <- node_elements %>% xml_find_all("./attributes/attribute")
# skip if there are no node attributes
if (length(attributes)) {
attrIds <- tibble(id = unlist(map(attributes, function(row) xml_attr(xml_parent(xml_parent(row)), "id"))))
nodeAttributes <- tibble(
id = attrIds$id,
name = attributes %>% xml_attr("name"),
class = attributes %>% xml_attr("class"),
value = attributes %>% xml_text(),
)
# which columns should be converted to numeric?
types <- nodeAttributes %>%
select(name, class) %>%
distinct()
convert <- filter(types, class == "java.lang.Double")$name
# convert to a format we can join to the links
nodeAttributes <- (nodeAttributes
%>% select(-class)
%>% pivot_wider(names_from = "name", values_from = "value")
%>% mutate_at(vars(one_of(convert)), as.double)
)
nodes <- nodes %>% left_join(nodeAttributes, by = "id")
}
cat("Links..")
link_elements <- network %>% xml_find_all("./links/link")
links <- tibble(
id = link_elements %>% xml_attr("id"),
from = link_elements %>% xml_attr("from"),
to = link_elements %>% xml_attr("to"),
length = link_elements %>% xml_attr("length") %>% parse_double(),
freespeed = link_elements %>% xml_attr("freespeed") %>% parse_double(),
capacity = link_elements %>% xml_attr("capacity") %>% parse_double(),
permlanes = link_elements %>% xml_attr("permlanes") %>% parse_double(),
modes = link_elements %>% xml_attr("modes"),
origid = link_elements %>% xml_attr("origid")
)
# merge node coordinates
links <- (links
%>% left_join(nodes, by = c("from" = "id"))
%>% left_join(nodes, by = c("to" = "id"), suffix = c(".from", ".to"))
)
# attributes don't have IDs on them! JFC, MATSim!
cat("Attributes..")
attributes <- link_elements %>% xml_find_all("./attributes/attribute")
# skip if there are no link-attributes
if (length(attributes)) {
attrIds <- tibble(id = unlist(map(attributes, function(row) xml_attr(xml_parent(xml_parent(row)), "id"))))
linkAttributes <- tibble(
id = attrIds$id,
name = attributes %>% xml_attr("name"),
class = attributes %>% xml_attr("class"),
value = attributes %>% xml_text(),
)
# which columns should be converted to numeric?
types <- linkAttributes %>%
select(name, class) %>%
distinct()
convert <- filter(types, class == "java.lang.Double")$name
# convert to a format we can join to the links
linkAttributes <- (linkAttributes
%>% select(-class)
%>% pivot_wider(names_from = "name", values_from = "value")
%>% mutate_at(vars(one_of(convert)), as.double)
)
links <- links %>% left_join(linkAttributes, by = "id", suffix = c(".link", ".attr"))
}
# Top-level network attributes
networkAttributes <- NULL
allNetworkAttributes <- network %>% xml_find_all("./attributes/attribute")
if (length(allNetworkAttributes)) {
networkAttributes <- tibble(
name = allNetworkAttributes %>% xml_attr("name"),
class = allNetworkAttributes %>% xml_attr("class"),
value = allNetworkAttributes %>% xml_text(),
)
# which columns should be converted to numeric?
types <- networkAttributes %>%
select(name, class) %>%
distinct()
convert <- filter(types, class == "java.lang.Double")$name
# convert to a format we can join to the links
networkAttributes <- (networkAttributes
%>% select(-class)
%>% pivot_wider(names_from = "name", values_from = "value")
%>% mutate_at(vars(one_of(convert)), as.double)
)
}
cat("Done!\n")
list("nodes" = nodes, "links" = links, "attributes" = networkAttributes)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.