Commit acf3fd13 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

add some comments for the docu, refactoring of duplicated code, improve...

add some comments for the docu, refactoring of duplicated code, improve performance of the transformation of the output into trajectory jave objects.
parent f5fa7acc
Pipeline #61911 passed with stage
in 52 seconds
......@@ -100,10 +100,20 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
});
}
public void init(final Map<Step, List<Agent>> agentsByStep, final Scenario vadere, final String projectPath) {
logger.info("start init postvis model");
init(vadere, projectPath);
/**
* Initialize the {@link PostvisualizationModel}.
*
* @param agentsByStep the trajectory information: a list of agent (their position, target, group...) sorted by the time step.
* @param scenario the scenario which was used to produce the output the PostVis will display.
* @param projectPath the path to the project.
*/
public void init(final Map<Step, List<Agent>> agentsByStep, final Scenario scenario, final String projectPath) {
logger.info("start the initialization of the PostvisualizationModel.");
init(scenario, projectPath);
this.agentsByStep = agentsByStep;
trajectories = new HashMap<>();
// to have fast access to the key values.
Map<Integer, Step> map = agentsByStep
.keySet().stream()
.sorted(stepComparator)
......@@ -118,21 +128,22 @@ public class PostvisualizationModel extends SimulationModel<PostvisualizationCon
for (int stepNumber = 1; stepNumber <= optLastStep.get().getStepNumber(); stepNumber++) {
if (map.containsKey(stepNumber)) {
steps.add(map.get(stepNumber));
for(Agent agent : agentsByStep.get(map.get(stepNumber))) {
if(!trajectories.containsKey(agent.getId())) {
trajectories.put(agent.getId(), new Trajectory(agent.getId()));
}
trajectories.get(agent.getId()).addStep(map.get(stepNumber), agent);
}
} else {
steps.add(new Step(stepNumber));
}
}
}
this.trajectories = agentsByStep
.entrySet()
.stream()
.flatMap(entry -> entry.getValue().stream())
.map(ped -> ped.getId())
.distinct()
.map(id -> new Trajectory(agentsByStep, id))
.collect(Collectors.toMap(t -> t.getPedestrianId(), t -> t));
for(Trajectory trajectory : trajectories.values()) {
trajectory.fill();
}
this.step = !steps.isEmpty() ? steps.get(0) : null;
logger.info("finished init postvis model");
......
......@@ -3,6 +3,7 @@ package org.vadere.simulator.projects.io;
import org.apache.commons.math3.util.Pair;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.dataprocessing.processor.PedestrianPositionProcessor;
import org.vadere.state.attributes.scenario.AttributesAgent;
......@@ -26,6 +27,18 @@ import java.util.stream.Collectors;
/**
* A TrajectoryReader is the counterpart of the {@link PedestrianPositionProcessor}.
*
* Output file assumptions:
* The TrajectoryReader assumes that the first row of the output is the headline and
* that there exist certain columns named:
* (id or pedestrianId) [mandatory],
* (step or timeStep) [mandatory],
* x [mandatory],
* y [mandatory],
* targetId [optional] and
* groupId [optional].
* The order of the rows (expect for the first row / header) can be arbitrary.
* Columns has to be separated by {@link TrajectoryReader#SPLITTER}
*/
public class TrajectoryReader {
......@@ -110,13 +123,9 @@ public class TrajectoryReader {
}
}
try {
if (pedIdIndex != -1 && xIndex != -1 && yIndex != -1 && stepIndex != -1 && groupIdIndex == -1) {
if (pedIdIndex != -1 && xIndex != -1 && yIndex != -1 && stepIndex != -1) {
// load default values with no groups
return readStandardTrajectoryFile();
} else if(pedIdIndex != -1 && xIndex != -1 && yIndex != -1 && stepIndex != -1) {//here groupIdIndex is != -1
// load values with group information
return readGroupTrajectoryFile();
}
else {
throw new IOException("could not read trajectory file, some colums are missing.");
......@@ -130,59 +139,48 @@ public class TrajectoryReader {
private Map<Step, List<Agent>> readStandardTrajectoryFile() throws IOException {
try (BufferedReader in = IOUtils.defaultBufferedReader(this.trajectoryFilePath)) {
return in.lines()
.skip(1) //Skip header line
.map(line -> line.split(SPLITTER))
.map(cells -> {
int step = Integer.parseInt(cells[stepIndex]);
int pedestrianId = Integer.parseInt(cells[pedIdIndex]);
VPoint pos = new VPoint(Double.parseDouble(cells[xIndex]), Double.parseDouble(cells[yIndex]));
int targetId = targetIdIndex != -1 ? Integer.parseInt(cells[targetIdIndex]) : -1;
Pedestrian ped = new Pedestrian(new AttributesAgent(this.attributesPedestrian, pedestrianId), new Random());
ped.setPosition(pos);
LinkedList<Integer> targets = new LinkedList<>();
targets.addFirst(targetId);
ped.setTargets(targets);
return Pair.create(new Step(Integer.parseInt(cells[0])), ped);
})
.collect(Collectors.groupingBy(Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.toList())));
return in.lines() // a stream of lines
.skip(1) // skip the first line i.e. the header
.map(line -> line.split(SPLITTER)) // split the line into string tokens
.map(rowTokens -> parseRowTokens(rowTokens)) // transform those tokens into a pair of java objects (step, agent)
.collect(Collectors.groupingBy(Pair::getKey, // group all agent objects by the step.
Collectors.mapping(Pair::getValue, Collectors.toList())));
} catch (Exception e){
logger.warn("could not read trajectory file. The file format might not be compatible or it is missing.");
throw e;
}
}
private Map<Step, List<Agent>> readGroupTrajectoryFile() throws IOException{
try (BufferedReader in = IOUtils.defaultBufferedReader(this.trajectoryFilePath)) {
return in.lines()
.skip(1) //Skip header line
.map(line -> line.split(SPLITTER))
.map(cells -> {
int step = Integer.parseInt(cells[stepIndex]);
int pedestrianId = Integer.parseInt(cells[pedIdIndex]);
VPoint pos = new VPoint(Double.parseDouble(cells[xIndex]), Double.parseDouble(cells[yIndex]));
int targetId = targetIdIndex != -1 ? Integer.parseInt(cells[targetIdIndex]) : -1;
int groupId = targetIdIndex != -1 ? Integer.parseInt(cells[groupIdIndex]) : -1;
Pedestrian ped = new Pedestrian(new AttributesAgent(this.attributesPedestrian, pedestrianId), new Random());
ped.setPosition(pos);
ped.addGroupId(groupId);
LinkedList<Integer> targets = new LinkedList<>();
targets.addFirst(targetId);
ped.setTargets(targets);
return Pair.create(new Step(Integer.parseInt(cells[0])), ped);
})
.collect(Collectors.groupingBy(Pair::getKey, Collectors.mapping(Pair::getValue, Collectors.toList())));
} catch (Exception e){
logger.warn("could not read trajectory file. The file format might not be compatible or it is missing.");
throw e;
/**
* transforms the string tokens of the row (i.e. the values generated by the output processor of one row)
* into a {@link Pair} of ({@link Step}, {@link Agent}).
*
* @param rowTokens string tokens of the row
* @return a {@link Pair} of ({@link Step}, {@link Agent})
*/
private Pair<Step, Agent> parseRowTokens(@NotNull final String[] rowTokens) {
// time step
int step = Integer.parseInt(rowTokens[stepIndex]);
// pedestrian id
int pedestrianId = Integer.parseInt(rowTokens[pedIdIndex]);
Pedestrian ped = new Pedestrian(new AttributesAgent(this.attributesPedestrian, pedestrianId), new Random());
// pedestrian position
VPoint pos = new VPoint(Double.parseDouble(rowTokens[xIndex]), Double.parseDouble(rowTokens[yIndex]));
// pedestrian target
int targetId = targetIdIndex != -1 ? Integer.parseInt(rowTokens[targetIdIndex]) : -1;
ped.setPosition(pos);
LinkedList<Integer> targets = new LinkedList<>();
targets.addFirst(targetId);
ped.setTargets(targets);
if(groupIdIndex != -1) {
int groupId = targetIdIndex != -1 ? Integer.parseInt(rowTokens[groupIdIndex]) : -1;
ped.addGroupId(groupId);
}
return Pair.create(new Step(step), ped);
}
}
package org.vadere.state.simulation;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
......@@ -8,13 +9,13 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.math3.optim.OptimizationData;
import org.jetbrains.annotations.NotNull;
import org.vadere.state.scenario.Agent;
import org.vadere.util.geometry.shapes.VPoint;
/**
* A Trajectory is a list of {@link org.vadere.state.scenario.Pedestrian} objects, that can be seen
* as pedestrian states of the same
* pedestrian. The representing pedestrian is the same, so all
* as pedestrian states of the same pedestrian. The representing pedestrian is the same, so all
* {@link org.vadere.state.scenario.Pedestrian} objects has
* the same id but the state of a pedestrian changes over time.
*
......@@ -31,6 +32,13 @@ public class Trajectory {
private int pedestrianId;
public Trajectory(final int pedestrianId) {
this.pedestrianId = pedestrianId;
this.trajectoryPoints = new HashMap<>();
this.firstStep = Optional.empty();
this.lastStep = Optional.empty();
}
public Trajectory(final Map<Step, List<Agent>> pedestrianByStep, final int pedestrianId) {
this.pedestrianId = pedestrianId;
......@@ -61,6 +69,42 @@ public class Trajectory {
}
}
public void fill() {
if(!trajectoryPoints.isEmpty()) {
for(Step step : trajectoryPoints.keySet()) {
if(!firstStep.isPresent() || firstStep.get().getStepNumber() > step.getStepNumber()) {
firstStep = Optional.of(step);
}
if(!lastStep.isPresent() || lastStep.get().getStepNumber() < step.getStepNumber()) {
lastStep = Optional.of(step);
}
}
int start = firstStep.get().getStepNumber();
int end = lastStep.get().getStepNumber();
for(int i = start+1; i < end; i++) {
Step currentStep = new Step(i);
if(!trajectoryPoints.containsKey(currentStep)) {
trajectoryPoints.put(currentStep, trajectoryPoints.get(new Step(currentStep.getStepNumber()-1)));
}
}
}
}
public void addStep(final Step step, @NotNull final Agent agent) {
if(!firstStep.isPresent() || firstStep.get().getStepNumber() > step.getStepNumber()) {
firstStep = Optional.of(step);
}
if(!lastStep.isPresent() || lastStep.get().getStepNumber() < step.getStepNumber()) {
firstStep = Optional.of(step);
}
trajectoryPoints.put(step, agent);
}
public Optional<Integer> getLifeTime() {
return getEndStep().isPresent() && getStartStep().isPresent() ?
Optional.of(getEndStep().get().getStepNumber() - getStartStep().get().getStepNumber()) :
......@@ -109,36 +153,6 @@ public class Trajectory {
return !trajectoryPoints.containsKey(step) && (!lastStep.isPresent() || lastStep.get().compareTo(step) <= 0);
}
/**
* Returns an Optional<Pedestrian> object. If the pedestrian is not appeared at the given time
* step,
* the Optional will be empty, the Optional will contain the Pedestrian object that is the last
* one
* in the list before (step+1).
*
* @param step the time step that specify the pedestrian state
* @return an Optional<Pedestrian> object which is empty if the pedestrian is not alive at the
* specific time step
*/
/*
* public Optional<Pedestrian> getAgent(final Step step) {
* Optional<Pedestrian> optionalPedestrian;
* if(trajectoryPoints.containsKey(step)) {
* optionalPedestrian = Optional.of(trajectoryPoints.get(step));
* }
* else {
* Optional<Step> optionalStep = sortedSteps.stream().filter(s -> s.getStepNumber() <=
* step.getStepNumber()).max((Step::compareTo));
* if(optionalStep.isPresent()) {
* optionalPedestrian = Optional.of(trajectoryPoints.get(optionalStep.get()));
* }
* else {
* optionalPedestrian = Optional.empty();
* }
* }
* return optionalPedestrian;
* }
*/
/**
* Returns an Optional<Pedestrian> object. If the pedestrain has not appeared at step, the
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment