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

Merge branch 'issue#96' into 'develop'

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

See merge request !31
parents f5fa7acc acf3fd13
Pipeline #61912 passed with stage
in 51 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