Skip to content

Commit

Permalink
blocked_road_use_case (#64)
Browse files Browse the repository at this point in the history
* make analysis trip based

* saving of full trip not needed anymore because trip files will be loaded in R anyways

* R analysis using matsim r functions based on java analysis

* save file in RStudio before commit

* finish up analysis

* analysis on inetrzonal drt legs

* replace logging statement using logger

* reduce complexity

* checkstyle
  • Loading branch information
simei94 authored Oct 12, 2023
1 parent 255344f commit 6b20a9b
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 76 deletions.
66 changes: 66 additions & 0 deletions src/main/R/drtAnalysis/DrtInterzonalTripsAnalysis.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
library(tidyverse)
library(matsim)
library(sf)

# input shp files and the corresponding crs are defined here
CRS <- 25832
zone1shpFile <- "../../shared-svn/projects/KelRide/data/ServiceAreas/2021-autumn-possibleAreasForAutomatedVehicles/Altstadt.shp"
zone2shpFile <- "../../shared-svn/projects/KelRide/data/ServiceAreas/2021-autumn-possibleAreasForAutomatedVehicles/Donaupark.shp"

# input legs or trips file is defined here
it <- 999
directory <- "Y:/net/ils/matsim-kelheim/run-roadBlock/output/kelheim-v2.0-network-with-pt.xml.gz-seed5678-CORE/"

itDir <- paste0(directory,"ITERS/it.",it,"/")
legsOrTripsFile <- paste0(itDir,list.files(path = itDir, pattern = "*legs_av*"))

zone1 <- st_read(zone1shpFile, crs=CRS)
zone2 <- st_read(zone2shpFile, crs=CRS)

legsOrTripsTable <- read.csv2(legsOrTripsFile) %>%
rename(start_x = "fromX",
start_y = "fromY",
end_x = "toX",
end_y = "toY")

# filter for legs / trips starting and ending in zones
departureInZone1 <- filterByRegion(legsOrTripsTable,zone1,crs=CRS,start.inshape = TRUE, end.inshape = FALSE) %>%
mutate(leg_id = paste0(personId,departureTime))
arrivalInZone1 <- filterByRegion(legsOrTripsTable,zone1,crs=CRS,start.inshape = FALSE, end.inshape = TRUE) %>%
mutate(leg_id = paste0(personId,departureTime))

departureInZone2 <- filterByRegion(legsOrTripsTable,zone2,crs=CRS,start.inshape = TRUE, end.inshape = FALSE) %>%
mutate(leg_id = paste0(personId,departureTime))
arrivalInZone2 <- filterByRegion(legsOrTripsTable,zone2,crs=CRS,start.inshape = FALSE, end.inshape = TRUE) %>%
mutate(leg_id = paste0(personId,departureTime))

#combine the above datasets to find legs / trips starting in one zone and ending in the other
zone1ToZone2 <- semi_join(departureInZone1, arrivalInZone2, by="leg_id")
zone2ToZone1 <- semi_join(departureInZone2, arrivalInZone1, by="leg_id")

interzonalLegs <- union(zone1ToZone2,zone2ToZone1)

meanTravTime <- mean(as.double(interzonalLegs$travelTime))
meanTravDist <- mean(as.double(interzonalLegs$travelDistance_m))
meanDirectTravDist <- mean(as.double(interzonalLegs$directTravelDistance_m))
meanWaitTime <- mean(as.double(interzonalLegs$waitTime))
interzonalLegsAbs <- nrow(interzonalLegs)
totalNoLegs <- nrow(legsOrTripsTable)
interzonalLegsRel <- interzonalLegsAbs / totalNoLegs

#save avg values into df
avgValues <- setNames(data.frame(matrix(ncol = 6, nrow = 0)), c("meanTravTime[s]", "meanTravDist[m]", "meanDirectTravDist[m]", "meanWaitTime[s]","interzonalLegsAbsolute", "interzonalLegsRelative"))

avgValuesDataset <- data.frame(meanTravTime, meanTravDist,meanDirectTravDist,meanWaitTime,interzonalLegsAbs,interzonalLegsRel)
names(avgValuesDataset) <- names(avgValues)
avgValues <- rbind(avgValues,avgValuesDataset)

if(!file.exists(paste0(directory,"analysis-stop-2-stop"))) {
print("creating analysis sub-directory")
dir.create(paste0(directory,"analysis-stop-2-stop"))
}

analysisDir <- paste0(directory,"/analysis-stop-2-stop/")

write.table(interzonalLegs,paste0(analysisDir,"drt_legs_av_interzonal_AS_DP.csv"),quote=FALSE, row.names=FALSE, dec=".", sep=";")
write.table(avgValues,paste0(analysisDir,"avgValues_legs_interzonal_AS_DP.tsv"),quote=FALSE, row.names=FALSE, dec=".", sep="\t")
94 changes: 94 additions & 0 deletions src/main/R/populationAnalysis/blockedRoadAgentsAnalysis.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
library(tidyverse)
library(matsim)
library(ggalluvial)
library(lubridate)


setwd("Y:/net/ils/matsim-kelheim/run-roadBlock/output/")

baseDir <- "Y:/net/ils/matsim-kelheim/run-roadBlock/output/kelheim-v2.0-network-with-pt.xml.gz-seed5678-CORE/"
policyDir <- "Y:/net/ils/matsim-kelheim/run-roadBlock/output/output-casekelheim-v2.0-network-with-pt_blocked-RegensburgerStr.xml.gz-seed5678-CORE/"

tsvFile <- "analysis-road-usage/blocked_infrastructure_trip_comparison.tsv"

ifelse(endsWith(policyDir, "/"),tsvFile <- tsvFile, tsvFile <- paste0("/",tsvFile))


affectedTrips <- read.csv2(paste0(policyDir,tsvFile), stringsAsFactors = FALSE, header = TRUE, encoding = "UTF-8", sep="\t")

tripsBase <- readTripsTable(pathToMATSimOutputDirectory = baseDir)
tripsPolicy <- readTripsTable(pathToMATSimOutputDirectory = policyDir)

# filter trips with usage of blocked infrastructure in base case only
tripsBase <- tripsBase %>%
filter(trip_id %in% affectedTrips$trip_id)

tripsPolicy <- tripsPolicy %>%
filter(trip_id %in% affectedTrips$trip_id)

# join relevant trips by id and join + filter important stats only
tripsCombined <- left_join(tripsBase, tripsPolicy, by = "trip_id") %>%
filter(trip_number.x == trip_number.y) %>%
select(trip_id,
trav_time.x,
trav_time.y,
traveled_distance.x,
traveled_distance.y,
modes.x,
modes.y,
main_mode.x,
main_mode.y,
wait_time.x,
wait_time.y,
euclidean_distance.x,
euclidean_distance.y) %>%
rename("trav_time_base" = trav_time.x,
"trav_time_policy" = trav_time.y,
"traveled_distance_base" = traveled_distance.x,
"traveled_distance_policy" = traveled_distance.y,
"modes_base" = modes.x,
"modes_policy" = modes.y,
"main_mode_base" = main_mode.x,
"main_mode_policy" = main_mode.y,
"wait_time_base" = wait_time.x,
"wait_time_policy" = wait_time.y,
"euclidean_distance_base" = euclidean_distance.x,
"euclidean_distance_policy" = euclidean_distance.y)

tripsCombined <- tripsCombined %>%
mutate(trav_time_diff_s = trav_time_policy - trav_time_base,
traveled_distance_diff_m = traveled_distance_policy - traveled_distance_base,
trav_time_base = seconds(trav_time_base),
trav_time_policy = seconds(trav_time_policy),
wait_time_base = seconds(wait_time_base),
wait_time_policy = seconds(wait_time_policy))

meanTravTimeBase <- mean(tripsCombined$trav_time_base)
meanTravTimePolicy <- mean(tripsCombined$trav_time_policy)
meanTravDistBase <- mean(tripsCombined$traveled_distance_base)
meanTravDistPolicy <- mean(tripsCombined$traveled_distance_policy)
meanEuclDistBase <- mean(tripsCombined$euclidean_distance_base)
meanEuclDistPolicy <- mean(tripsCombined$euclidean_distance_policy)
meanWaitTimeBase <- mean(tripsCombined$wait_time_base)
meanWaitTimePolicy <- mean(tripsCombined$wait_time_policy)

tripsChangedMainMode <- tripsCombined %>%
filter(main_mode_base != main_mode_policy)

noTripsChangedMainMode <- nrow(tripsChangedMainMode)

#save avg values into df
avgValues <- setNames(data.frame(matrix(ncol = 9, nrow = 0)), c("meanTravTimeBase[s]", "meanTravTimePolicy[s]", "meanTravDistBase[m]", "meanTravDistPolicy[m]", "meanEuclDistBase[m]",
"meanEuclDistPolicy[m]", "meanWaitTimeBase[s]", "meanWaitTimePolicy[s]","nrTripsChangedMainMode"))

avgValuesDataset <- data.frame(meanTravTimeBase, meanTravTimePolicy,meanTravDistBase,meanTravDistPolicy,meanEuclDistBase,meanEuclDistPolicy,meanWaitTimeBase,meanWaitTimePolicy,noTripsChangedMainMode)
names(avgValuesDataset) <- names(avgValues)
avgValues <- rbind(avgValues,avgValuesDataset)

tsvFileName <- paste0("avg_params_blocked_infrastructure_agents.tsv")
write.table(avgValues,paste0(policyDir,"analysis-road-usage/",tsvFileName),quote=FALSE, row.names=FALSE, dec=".", sep="\t")
print(paste0("avg values for agents affected by blocked infrastructure ",policyDir,"analysis-road-usage/",tsvFileName))




Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.locationtech.jts.geom.Geometry;
Expand All @@ -22,6 +23,7 @@
import picocli.CommandLine;

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
Expand All @@ -31,7 +33,7 @@
/**
* Analyse routes for agents which use a certain infrastructure segment.
* 1) Retrieves agents which use the infrastructure (e.g. in base case)
* 2) Searches for the (new) routes of the agents in a policy case
* 2) Save trips of those agents to tsv file for further R analysis.
*
* @author Simon Meinhardt (simei94)
*/
Expand All @@ -48,7 +50,7 @@ class BlockedInfrastructureRouteAnalysis implements MATSimAppCommand {
@CommandLine.Mixin
private ShpOptions shp = new ShpOptions();

Map<Id<Person>, Map<Integer, Leg>> relevantLegsBase = new HashMap<>();
Map<Id<Person>, Map<Integer, TripStructureUtils.Trip>> relevantTripsBase = new HashMap<>();

public static void main(String[] args) {
new BlockedInfrastructureRouteAnalysis().execute(args);
Expand All @@ -63,7 +65,6 @@ public Integer call() throws Exception {

Path basePopulationPath = globFile(directoryBase, "*output_plans*");

Path policyPopulationPath = globFile(directoryBase, "*output_plans*");
//output will be written into policy case folder
Path outputFolder = Path.of(directoryPolicy.toString() + "/analysis-road-usage");

Expand All @@ -78,63 +79,44 @@ public Integer call() throws Exception {

Population populationBase = ScenarioUtils.loadScenario(config).getPopulation();

config.plans().setInputFile(policyPopulationPath.toString());
Population populationPolicy = ScenarioUtils.loadScenario(config).getPopulation();

//get links, which are affected by blocked infrastructure
List<String> blockedLinks = getBlockedLinks(network, blockedInfrastructureArea);

relevantLegsBase = getLegsFromPlans(populationBase, blockedLinks);
Map<Id<Person>, Map<Integer, Leg>> relevantLegsPolicy = getLegsFromPlans(populationPolicy, blockedLinks);
relevantTripsBase = getTripsFromPlans(populationBase, blockedLinks);

//writeResults
String outputFile = outputFolder + "/" + "blocked_infrastructure_leg_comparison.tsv";
String outputFile = outputFolder + "/" + "blocked_infrastructure_trip_comparison.tsv";
CSVPrinter tsvPrinter = new CSVPrinter(new FileWriter(outputFile), CSVFormat.TDF);
List<String> header = new ArrayList<>();
header.add("person_id");
header.add("tt_s_base");
header.add("tt_s_policy");
header.add("dist_m_base");
header.add("dist_m_policy");
header.add("mode_base");
header.add("mode_policy");
header.add("startLink_base");
header.add("startLink_policy");
header.add("endLink_base");
header.add("endLink_policy");
header.add("route_description_base");
header.add("route_description_policy");

tsvPrinter.printRecord(header);

for (Id<Person> personId : relevantLegsBase.keySet()) {

for (Integer index : relevantLegsBase.get(personId).keySet()) {

Map<Integer, Leg> basePersonStats = relevantLegsBase.get(personId);
Map<Integer, Leg> policyPersonStats = relevantLegsPolicy.get(personId);

List<String> entry = new ArrayList<>();
entry.add(personId.toString());
entry.add(String.valueOf(basePersonStats.get(index).getRoute().getTravelTime().seconds()));
entry.add(String.valueOf(policyPersonStats.get(index).getRoute().getTravelTime().seconds()));
entry.add(String.valueOf(basePersonStats.get(index).getRoute().getDistance()));
entry.add(String.valueOf(policyPersonStats.get(index).getRoute().getDistance()));
entry.add(basePersonStats.get(index).getMode());
entry.add(policyPersonStats.get(index).getMode());
entry.add(basePersonStats.get(index).getRoute().getStartLinkId().toString());
entry.add(policyPersonStats.get(index).getRoute().getStartLinkId().toString());
entry.add(basePersonStats.get(index).getRoute().getEndLinkId().toString());
entry.add(policyPersonStats.get(index).getRoute().getEndLinkId().toString());
entry.add(basePersonStats.get(index).getRoute().getRouteDescription());
entry.add(policyPersonStats.get(index).getRoute().getRouteDescription());

tsvPrinter.printRecord(entry);
try {
List<String> header = new ArrayList<>();
header.add("person_id");
header.add("trip_number");
header.add("trip_id");

tsvPrinter.printRecord(header);

for (Map.Entry<Id<Person>, Map<Integer, TripStructureUtils.Trip>> entry : relevantTripsBase.entrySet()) {

Integer tripNumber;

for (Integer index : relevantTripsBase.get(entry.getKey()).keySet()) {

tripNumber = index + 1;

List<String> outputEntry = new ArrayList<>();
outputEntry.add(entry.getKey().toString());
outputEntry.add(tripNumber.toString());
outputEntry.add(entry.getKey() + "_" + tripNumber);

tsvPrinter.printRecord(outputEntry);
}
}
} catch (IOException e) {
log.log(Level.FATAL, e);
} finally {
tsvPrinter.close();
log.log(Level.INFO, "Analysis output has been written to: {}", outputFile);
}
tsvPrinter.close();

log.info("Analysis output has been written to: " + outputFile);

return 0;
}
Expand All @@ -144,51 +126,62 @@ private List<String> getBlockedLinks(Network network, Geometry geometry) {
List<String> blockedLinks = new ArrayList<>();

for (Link link : network.getLinks().values()) {
if (!link.getId().toString().contains("pt_")) {
if (isInsideArea(link, geometry)) {
blockedLinks.add(link.getId().toString());
}
if (!link.getId().toString().contains("pt_") && isInsideArea(link, geometry)) {
blockedLinks.add(link.getId().toString());
}
}
return blockedLinks;
}

private Map<Id<Person>, Map<Integer, Leg>> getLegsFromPlans(Population population, List<String> blockedLinks) {
private Map<Id<Person>, Map<Integer, TripStructureUtils.Trip>> getTripsFromPlans(Population population, List<String> blockedLinks) {

Map<Id<Person>, Map<Integer, Leg>> relevantLegs = new HashMap<>();
Map<Id<Person>, Map<Integer, TripStructureUtils.Trip>> relevantTrips = new HashMap<>();

if (relevantLegsBase.size() < 1) {
if (relevantTripsBase.size() < 1) {
//base case
log.info("Analyzing legs on blocked infrastructure for base case population");

for ( Person person : population.getPersons().values()) {
//check if blocked link is part of leg-route
for ( Leg leg : TripStructureUtils.getLegs(person.getSelectedPlan())) {
for ( String linkId : blockedLinks ) {
if (leg.getRoute().getRouteDescription().contains(linkId)) {
relevantLegs.putIfAbsent(person.getId(), new HashMap<>());
relevantLegs.get(person.getId()).put(person.getSelectedPlan().getPlanElements().indexOf(leg), leg);
continue;
}
}
}



List<TripStructureUtils.Trip> trips = TripStructureUtils.getTrips(person.getSelectedPlan());

getTripsFromPersons(blockedLinks, person, trips, relevantTrips);
}

} else {
//policy case
//get corresponding legs to base case legs (where the now-blocked infrastructure is used)
//get corresponding trips to base case trips (where the now-blocked infrastructure is used)
log.info("Analyzing legs on blocked infrastructure for policy case population");

for (Id<Person> personId : relevantLegsBase.keySet()) {
for ( Integer index : relevantLegsBase.get(personId).keySet()) {
relevantLegs.putIfAbsent(personId, new HashMap<>());
Leg policyLeg = (Leg) population.getPersons().get(personId).getSelectedPlan().getPlanElements().get(index);
relevantLegs.get(personId).put(population.getPersons().get(personId).getSelectedPlan().getPlanElements().indexOf(policyLeg),
policyLeg);
for (Map.Entry<Id<Person>, Map<Integer, TripStructureUtils.Trip>> entry : relevantTripsBase.entrySet()) {
for ( Integer index : relevantTripsBase.get(entry.getKey()).keySet()) {
relevantTrips.putIfAbsent(entry.getKey(), new HashMap<>());

TripStructureUtils.Trip policyTrip = TripStructureUtils.getTrips(population.getPersons().get(entry.getKey()).getSelectedPlan()).get(index);

relevantTrips.get(entry.getKey()).put(index, policyTrip);
}
}
}

return relevantLegs;
return relevantTrips;
}

private static void getTripsFromPersons(List<String> blockedLinks, Person person, List<TripStructureUtils.Trip> trips, Map<Id<Person>, Map<Integer, TripStructureUtils.Trip>> relevantTrips) {
for (int i = 0; i < trips.size(); i++) {
for (Leg leg : trips.get(i).getLegsOnly()) {
for ( String linkId : blockedLinks) {
if (leg.getRoute().getRouteDescription().contains(linkId)) {
relevantTrips.putIfAbsent(person.getId(), new HashMap<>());
relevantTrips.get(person.getId()).put(i, trips.get(i));
continue;
}
}
}
}
}

static boolean isInsideArea(Link link, Geometry geometry) {
Expand Down

0 comments on commit 6b20a9b

Please sign in to comment.