<<<<<<< HEAD
package simulation;
import helpers.RandomNumberProvider;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;
import roadnetwork.Edge;
import roadnetwork.Lane;
import roadnetwork.RoadNetwork;
import trafficdefinition.Accident;
import trafficdefinition.AreaFlow;
import trafficdefinition.Flow;
import trafficdefinition.HotSpot;
import trafficdefinition.RandomTrafficDefinitionLayer;
import trafficdefinition.School;
import trafficdefinition.TrafficArea;
import trafficdefinition.TrafficDefinitionElement;
import trafficdefinition.UserDefinedTrafficDefinitionLayer;
import classes.Constants;
import classes.Pair;
import classes.TypeSelection;
import enums.SchoolType;
/**
* Helper class that generates traffic from user defined traffic elements
*
*/
public class TrafficGenerator {
/**
* Method that generates traffic for a user-defined traffic definition layer
*
* @param roadNetwork
* the road network for which to generate the traffic
* @param layer
* the layer to generate traffic for
* @param tripBuilder
* the StringBuilder to place the generated trips in
* @param accidentRouteBuilder
* the StringBuilder to place the generated routes for accidents
* @throws Exception
*/
public static void GenerateUserDefinedLayerTraffic(RoadNetwork roadNetwork, UserDefinedTrafficDefinitionLayer layer, SUMOInstructionList<Trip> tripsList, SUMOInstructionList<Route> accidentRoutesList) throws Exception {
// Get the layer's elements
List<TrafficDefinitionElement> layerElements = layer.getElements();
// Create the trips for the elements
for (TrafficDefinitionElement t : layerElements) {
// Take into account only enabled elements
if (t.isEnabled()) {
if (t instanceof Flow) {
tripsList.addAll(GenerateFlowTraffic((Flow) t));
} else if (t instanceof AreaFlow) {
tripsList.addAll(GenerateAreaFlowTraffic((AreaFlow) t, roadNetwork));
} else if (t instanceof HotSpot) {
tripsList.addAll(GenerateHotSpotTraffic((HotSpot) t, roadNetwork));
} else if (t instanceof Accident) {
accidentRoutesList.addAll(GenerateAccidentTraffic((Accident) t, roadNetwork));
}
}
}
}
/**
* Method that generates traffic for a random traffic definition layer
*
* @param roadNetwork
* the road network for which to generate the traffic
* @param layer
* the layer to generate traffic for
* @param tripsList
* the List to place the generated trips in
* @throws Exception
*/
public static void GenerateRandomLayerTraffic(RoadNetwork roadNetwork, RandomTrafficDefinitionLayer layer, SUMOInstructionList<Trip> tripsList) throws Exception {
Random r = RandomNumberProvider.getRandom();
// Get all the edges in the road network
List<Edge> allEdges = new ArrayList<Edge>();
allEdges = roadNetwork.getEdges();
int totalNetworkEdges = allEdges.size();
String color = "1,0,0";
// Simple validation
if (totalNetworkEdges == 0) {
return;
}
int emissionDuration = layer.getEndingTime() - layer.getStartingTime();
int totalVehiclesToEmit = layer.getVehiclesPerSecond() * emissionDuration;
// For each vehicle
for (int i = 0; i < totalVehiclesToEmit; i++) {
// Get the vehicle's type based on the user selection
VehicleType vehicleType = layer.getVehicleSelection().getRandomType();
// Get a random edge in the network
Edge randomNetworkEdge1 = allEdges.get(r.nextInt(totalNetworkEdges));
// Get a random edge in the network
Edge randomNetworkEdge2 = allEdges.get(r.nextInt(totalNetworkEdges));
// Get a random time between the emission starting and ending time
int timeToLeave = layer.getStartingTime() + r.nextInt(layer.getEndingTime() + 1 - layer.getStartingTime());
// Add the incoming vehicle trip to the output
tripsList.add(new Trip(timeToLeave,"<tripdef id=\"" + layer.getName() + "-In-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(timeToLeave) + "\" from=\"" + randomNetworkEdge1.getId() + "\" to=\"" + randomNetworkEdge2.getId() + "\" color=\"" + color + "\" type=\"" + vehicleType.getName() + "\" />\n"));
}
}
/**
* Method that generates traffic for activity based layers
*
* @param roadNetwork
* the underlying road network
* @param projectJobTypes
* the project's job types
* @param vehicleTypes
* the layer's selected vehicle types
* @param activityBasedTrafficDefinitionElements
* list of statistical and demographic elements (traffic areas
* and schools)
* @param tripsList
* @param routesList
* @throws Exception
*/
public static void GenerateActivityBasedTraffic(RoadNetwork roadNetwork, List<JobType> projectJobTypes, TypeSelection<VehicleType> vehicleTypes, List<TrafficDefinitionElement> activityBasedTrafficDefinitionElements, SUMOInstructionList<Trip> tripsList, SUMOInstructionList<Route> routesList) throws Exception {
// Sort the traffic areas and schools into separate lists
List<TrafficArea> areas = new ArrayList<TrafficArea>();
List<School> schools = new ArrayList<School>();
for (TrafficDefinitionElement t : activityBasedTrafficDefinitionElements) {
if (t instanceof TrafficArea) {
areas.add((TrafficArea) t);
} else if (t instanceof School) {
schools.add((School) t);
}
}
// Assign addresses to schools and initialize capacities
for (School school : schools) {
school.setAvailableCapacity(school.getCapacity());
school.setClosestEdge(roadNetwork.findClosestEdge(school.getLocation()));
}
// For every job type find for every area the available work positions
// and put them in a hashtable
Hashtable<JobType, List<Pair<TrafficArea, Integer>>> workPositionsPerJobTypePerArea = new Hashtable<JobType, List<Pair<TrafficArea, Integer>>>();
for (JobType projectJobType : projectJobTypes) {
// Create a list that will hold the available work positions for
// this job type per area
List<Pair<TrafficArea, Integer>> areaPositions = new ArrayList<Pair<TrafficArea, Integer>>();
// Loop through all areas
for (TrafficArea area : areas) {
// Get the possibility for this job and this area
float areaJobPossibility = area.getWorkersJobSelection().getTypePossibility(projectJobType);
// If the possibility for this job for this area is larger than
// 0 then add the area to the list.
if (areaJobPossibility > 0) {
areaPositions.add(new Pair<TrafficArea, Integer>(area, Math.round(areaJobPossibility * area.getWorkPositions())));
}
}
// Insert the list to the hashtable
workPositionsPerJobTypePerArea.put(projectJobType, areaPositions);
}
// Variable used to assign house ids
int houseID = 0;
// Create virtual population for each traffic area
for (TrafficArea area : areas) {
// Number of people to create
int unassignedPeople = area.getPopulation();
// A list of the virtual houses that will be created at this area
List<House> areaHouses = new ArrayList<House>();
Random r = RandomNumberProvider.getRandom();
// Create area houses
while (unassignedPeople > 0) {
House house = new House(area, houseID++);
// Set the house's address
Point2D.Double houseLocation = area.getRandomPointInArea();
house.setAddress(roadNetwork.findClosestEdge(houseLocation));
house.setLocation(houseLocation);
// Create house residents
// Number of adults and children is gaussian distribution
// mith mean as specified by user and standard deviation 0.8
int houseAdults = Math.round((float) (r.nextGaussian() * 0.8 + area.getAverageAdultsPerHouse()));
if (houseAdults < 1) {
houseAdults = 1;
}
int houseChildren = cern.jet.random.Poisson.staticNextInt(area.getAverageChildrenPerHouse());
house.createAdults(houseAdults, area.getPossibilityAdultIsDriver(), area.getPossibilityAdultHasJob());
house.createChildren(houseChildren);
house.assignVehiclesToDrivers(area.getPossibilityDriverHasCar(), vehicleTypes);
// Find closest school for every child in the house based on the
// child's age and the school location and capacity
for (Child child : house.getChildren()) {
School closestAvailableSchool = FindClosestSchoolToLocation(schools, child.getSchoolType(), house.getLocation());
child.setSchool(closestAvailableSchool);
if (closestAvailableSchool != null) {
closestAvailableSchool.setAvailableCapacity(closestAvailableSchool.getAvailableCapacity() - 1);
}
}
// Add the house to the area's houses
areaHouses.add(house);
// Update helper variable
unassignedPeople -= house.getNumberOfResidents();
}
// Loop through all houses and assign jobs to all
// working adults
for (House house : areaHouses) {
// For each working adult in the house
for (Adult adult : house.getWorkingAdults()) {
// Get the adult's job based on the user's selection
JobType job = area.getResidentsJobSelection().getRandomType();
List<Pair<TrafficArea, Integer>> jobAreaPositions = workPositionsPerJobTypePerArea.get(job);
// If we have areas with available work positions
if (jobAreaPositions.size() > 0) {
// Get a random area
int i = r.nextInt(jobAreaPositions.size());
// Get a random edge in the area
Point2D.Double jobLocation = jobAreaPositions.get(i).getFirst().getRandomPointInArea();
// Assign the job to the adult
adult.setJobLocation(job, roadNetwork.findClosestEdge(jobLocation));
// If this was the last job position of this kind in
// this area
if (jobAreaPositions.get(i).getSecond() == 1) {
// Remove the area - it is full
jobAreaPositions.remove(i);
} else {
// Decrease the available work positions
jobAreaPositions.get(i).setSecond(jobAreaPositions.get(i).getSecond() - 1);
}
}
// If no available work positions exist then the adult is
// unemployed
else {
adult.setHasJob(false);
}
}
}
// Create activities for the people in each house
for (House house : areaHouses) {
System.out.println(area.getName() + " " + String.valueOf(house.getId()));
house.createActivities(tripsList, routesList);
}
}
}
/**
* Generates traffic for a {@link HotSpot}
*
* @param spot
* the hotspot for which to generate traffic
* @param roadNetwork
* the underlying road network
* @return list of generated trips
*/
private static SUMOInstructionList<Trip> GenerateHotSpotTraffic(HotSpot spot, RoadNetwork roadNetwork) {
Random r = RandomNumberProvider.getRandom();
SUMOInstructionList<Trip> trips = new SUMOInstructionList<Trip>();
// Get the edges that lie within the hotspot
List<Edge> hotspotEdges = new ArrayList<Edge>();
hotspotEdges = roadNetwork.SelectEdges(spot.getArea());
int totalHotspotEdges = hotspotEdges.size();
// Get all the edges in the road network
List<Edge> allEdges = new ArrayList<Edge>();
allEdges = roadNetwork.getEdges();
// Remove the hotspot edges
for (Edge e : hotspotEdges) {
if (allEdges.contains(e)) {
allEdges.remove(e);
}
}
int totalNetworkEdges = allEdges.size();
String color = new Float(spot.getColor().getRed() / 255f).toString() + "," + new Float(spot.getColor().getGreen() / 255f).toString() + "," + new Float(spot.getColor().getBlue() / 255f).toString();
// Simple validation
if ((totalNetworkEdges == 0) || (totalHotspotEdges == 0)) {
return null;
}
// For each vehicle
for (int i = 0; i < spot.getNumberOfVehicles(); i++) {
// Get the vehicle's type based on the user selection
VehicleType vehicleType = spot.getVehicleSelection().getRandomType();
// Get a random edge in the hotspot
Edge randomHotspotEdge = hotspotEdges.get(r.nextInt(totalHotspotEdges));
// Get a random edge in the network
Edge randomNetworkEdge = allEdges.get(r.nextInt(totalNetworkEdges));
// If the hotspot is incoming (vehicles from anywhere to the
// hotspot)
if (spot.isDirectionIn()) {
int timeOfDepartureFromSource = 0;
// If the time is specified as the time of departure from the
// source
if (spot.getDirectionInType() == HotSpot.DirectionInTimeType.TimeOfDepartureFromSource) {
// Get a random time between the incoming begin time and end
// time
timeOfDepartureFromSource = spot.getDirectionInBeginTime() + r.nextInt(spot.getDirectionInEndTime() + 1 - spot.getDirectionInBeginTime());
}
// If the time is specified as the time of arrival to the
// hotspot
else if (spot.getDirectionInType() == HotSpot.DirectionInTimeType.TimeOfArrivalToDestination) {
// Try to estimate the distance that the vehicle will need
// to travel
float distanceToTravel = randomHotspotEdge.DistanceFrom(randomNetworkEdge);
// Estimate the time needed to cover this distance
int estimatedTravelTime = (int) Math.round(distanceToTravel / Constants.averageSpeed);
// Get a random time between the incoming begin time and end
// time minus the time needed to travel
timeOfDepartureFromSource = spot.getDirectionInBeginTime() + r.nextInt(spot.getDirectionInEndTime() + 1 - spot.getDirectionInBeginTime()) - estimatedTravelTime;
// A vehicle can't start with a negative departure time
timeOfDepartureFromSource = Math.min(timeOfDepartureFromSource, 0);
}
// Add the incoming vehicle trip to the output
trips.add(new Trip(timeOfDepartureFromSource, "<tripdef id=\"" + spot.getName() + "-In-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(timeOfDepartureFromSource) + "\" from=\"" + randomNetworkEdge.getId() + "\" to=\"" + randomHotspotEdge.getId() + "\" color=\"" + color + "\" type=\"" + vehicleType.getName() + "\" />\n"));
}
// If the hotspot is outgoing (vehicles from the hotspot to
// anywhere)
if (spot.isDirectionOut()) {
// Get a random time between the outgoing begin time and end
// time
int timeToLeaveSpot = spot.getDirectionOutBeginTime() + r.nextInt(spot.getDirectionOutEndTime() + 1 - spot.getDirectionOutBeginTime());
// Add the outgoing vehicle trip to the output
trips.add(new Trip(timeToLeaveSpot, "<tripdef id=\"" + spot.getName() + "-Out-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(timeToLeaveSpot) + "\" from=\"" + randomHotspotEdge.getId() + "\" to=\"" + randomNetworkEdge.getId() + "\" color=\"" + color + "\" type=\"" + vehicleType.getName() + "\" />\n"));
}
}
return trips;
}
/**
* Generates traffic for a {@link Flow}
*
* @param flow
* the flow for which to generate traffic
* @return list of generated trips
*/
private static SUMOInstructionList<Trip> GenerateFlowTraffic(Flow flow) {
Random r = RandomNumberProvider.getRandom();
SUMOInstructionList<Trip> trips = new SUMOInstructionList<Trip>();
// For each vehicle
for (int i = 0; i < flow.getNumberOfVehicles(); i++) {
// Get a random time between the begin time and end time
int departureTime = flow.getBeginTime() + r.nextInt(flow.getEndTime() + 1 - flow.getBeginTime());
String color = new Float(flow.getColor().getRed() / 255f).toString() + "," + new Float(flow.getColor().getGreen() / 255f).toString() + "," + new Float(flow.getColor().getBlue() / 255f).toString();
// Create the trip
trips.add(new Trip(departureTime, "<tripdef id=\"" + flow.getName() + "-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(departureTime) + "\" from=\"" + flow.getStart().getId() + "\" to=\"" + flow.getEnd().getId() + "\" color=\"" + color + "\" type=\"" + flow.getVehicleSelection().getRandomType().getName() + "\" />\n"));
}
return trips;
}
/**
* Generates traffic for an {@link Accident}
*
* @param accident
* the accident for which to generate traffic
* @param roadNetwork
* the road network
* @return list of generated routes
* @throws Exception
*/
private static SUMOInstructionList<Route> GenerateAccidentTraffic(Accident accident, RoadNetwork roadNetwork) throws Exception {
// Random r = RandomNumberProvider.getRandom();
// List<Edge> networkEdges = roadNetwork.getEdges();
SUMOInstructionList<Route> routes = new SUMOInstructionList<Route>();
// For each affected lane
for (Pair<Lane, Boolean> affectedLane : accident.getAffectedLanes()) {
if (affectedLane.getSecond()) {
/*
* // Create a route for a vehicle starting at the edge that the //
* accident happens and ending at a random network edge passing //
* first through an edge connected to the lane List<Edge>
* routeEdges = new ArrayList<Edge>();
*
* routeEdges.add(accident.getEdge());
*
* if (affectedLane.getFirst().getConnectedEdges().size() > 0) {
* Edge connectedEdge =
* roadNetwork.findEdge(affectedLane.getFirst().getConnectedEdges().get(0));
*
* if (connectedEdge != null) { routeEdges.add(connectedEdge); } }
*
* routeEdges.add(networkEdges.get(r.nextInt(networkEdges.size()))); //
* Expand the route for the trip String route =
* MultipleTripExpander.ExpandTrips(routeEdges);
*/
// Create a route for a vehicle starting at the edge that the
// accident happens and ending at an edge connected to the lane
String route = accident.getEdge().getId();
if (affectedLane.getFirst().getConnectedEdges().size() > 0) {
Edge connectedEdge = roadNetwork.findEdge(affectedLane.getFirst().getConnectedEdges().get(0));
if (connectedEdge != null) {
route += " " + connectedEdge.getId();
}
}
routes.add(new Route(accident.getStartingTime(), "<vehicle id=\"Accident-" + accident.getName() + "-" + affectedLane.getFirst().getId() + "\" type=\"Default\" depart=\"" + String.valueOf(accident.getStartingTime()) + "\" color=\"1,0,0\">\n" + " <route color=\"1,0,0\">" + route + "</route>\n" + " <stop lane=\"" + affectedLane.getFirst().getId() + "\" pos=\"" + accident.getEdgeRelativeLocation() + "\" duration=\"" + String.valueOf(accident.getEndingTime() - accident.getStartingTime()) + "\"/>\n" + "</vehicle>\n"));
}
}
return routes;
}
/**
* Generates traffic for an {@link AreaFlow}
*
* @param areaFlow
* the area flow for which to generate traffic
* @param roadNetwork
* the underlying road network
* @return list of generated trips
*/
private static SUMOInstructionList<Trip> GenerateAreaFlowTraffic(AreaFlow areaFlow, RoadNetwork roadNetwork) {
Random r = RandomNumberProvider.getRandom();
SUMOInstructionList<Trip> trips = new SUMOInstructionList<Trip>();
// Get the edges belonging in the start area
List<Edge> fromAreaEdges = new ArrayList<Edge>();
fromAreaEdges = roadNetwork.SelectEdges(areaFlow.getStartArea());
int totalFromAreaEdges = fromAreaEdges.size();
// Get the edges belonging in the end area
List<Edge> toAreaEdges = new ArrayList<Edge>();
toAreaEdges = roadNetwork.SelectEdges(areaFlow.getEndArea());
int totalToAreaEdges = toAreaEdges.size();
// Simple validation
if ((totalToAreaEdges == 0) || (totalFromAreaEdges == 0)) {
return null;
}
// For each vehicle
for (int i = 0; i < areaFlow.getNumberOfVehicles(); i++) {
// Get a random source and destination edge
Edge randomFromEdge = fromAreaEdges.get(r.nextInt(totalFromAreaEdges));
Edge randomToEdge = toAreaEdges.get(r.nextInt(totalToAreaEdges));
// Get a random time between the begin time and end time
int departureTime = areaFlow.getBeginTime() + r.nextInt(areaFlow.getEndTime() + 1 - areaFlow.getBeginTime());
String color = new Float(areaFlow.getColor().getRed() / 255f).toString() + "," + new Float(areaFlow.getColor().getGreen() / 255f).toString() + "," + new Float(areaFlow.getColor().getBlue() / 255f).toString();
// Create the trip
trips.add(new Trip(departureTime, "<tripdef id=\"" + areaFlow.getName() + "-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(departureTime) + "\" from=\"" + randomFromEdge.getId() + "\" to=\"" + randomToEdge.getId() + "\" color=\"" + color + "\" type=\"" + areaFlow.getVehicleSelection().getRandomType().getName() + "\" />\n"));
}
return trips;
}
/**
* Finds the closest school of the specified type to a location
*
* @param schools
* the set of schools to search
* @param type
* the type of the school to find
* @param location
* the location to search near for
* @return the closest school near the specified location
*/
private static School FindClosestSchoolToLocation(List<School> schools, SchoolType type, Point2D.Double location) {
School closestSchool = null;
double minimumSchoolDistance = Float.MAX_VALUE;
// Loop through all schools
for (School school : schools) {
if ((school.getSchoolType() == type) && (school.getAvailableCapacity() > 0)) {
// Get the distance between the school and the location
double schoolDistance = school.getLocation().distance(location);
// If it is smaller than all previous distances
if (schoolDistance < minimumSchoolDistance) {
minimumSchoolDistance = schoolDistance;
closestSchool = school;
}
}
}
return closestSchool;
}
}
=======
package simulation;
import helpers.RandomNumberProvider;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;
import roadnetwork.Edge;
import roadnetwork.Lane;
import roadnetwork.RoadNetwork;
import trafficdefinition.Accident;
import trafficdefinition.AreaFlow;
import trafficdefinition.Flow;
import trafficdefinition.HotSpot;
import trafficdefinition.RandomTrafficDefinitionLayer;
import trafficdefinition.School;
import trafficdefinition.TrafficArea;
import trafficdefinition.TrafficDefinitionElement;
import trafficdefinition.UserDefinedTrafficDefinitionLayer;
import classes.Constants;
import classes.Pair;
import classes.TypeSelection;
import enums.SchoolType;
/**
* Helper class that generates traffic from user defined traffic elements
*
*/
public class TrafficGenerator {
/**
* Method that generates traffic for a user-defined traffic definition layer
*
* @param roadNetwork
* the road network for which to generate the traffic
* @param layer
* the layer to generate traffic for
* @param tripBuilder
* the StringBuilder to place the generated trips in
* @param accidentRouteBuilder
* the StringBuilder to place the generated routes for accidents
* @throws Exception
*/
public static void GenerateUserDefinedLayerTraffic(RoadNetwork roadNetwork, UserDefinedTrafficDefinitionLayer layer, SUMOInstructionList<Trip> tripsList, SUMOInstructionList<Route> accidentRoutesList) throws Exception {
// Get the layer's elements
List<TrafficDefinitionElement> layerElements = layer.getElements();
// Create the trips for the elements
for (TrafficDefinitionElement t : layerElements) {
// Take into account only enabled elements
if (t.isEnabled()) {
if (t instanceof Flow) {
tripsList.addAll(GenerateFlowTraffic((Flow) t));
} else if (t instanceof AreaFlow) {
tripsList.addAll(GenerateAreaFlowTraffic((AreaFlow) t, roadNetwork));
} else if (t instanceof HotSpot) {
tripsList.addAll(GenerateHotSpotTraffic((HotSpot) t, roadNetwork));
} else if (t instanceof Accident) {
accidentRoutesList.addAll(GenerateAccidentTraffic((Accident) t, roadNetwork));
}
}
}
}
/**
* Method that generates traffic for a random traffic definition layer
*
* @param roadNetwork
* the road network for which to generate the traffic
* @param layer
* the layer to generate traffic for
* @param tripsList
* the List to place the generated trips in
* @throws Exception
*/
public static void GenerateRandomLayerTraffic(RoadNetwork roadNetwork, RandomTrafficDefinitionLayer layer, SUMOInstructionList<Trip> tripsList) throws Exception {
Random r = RandomNumberProvider.getRandom();
// Get all the edges in the road network
List<Edge> allEdges = new ArrayList<Edge>();
allEdges = roadNetwork.getEdges();
int totalNetworkEdges = allEdges.size();
String color = "1,0,0";
// Simple validation
if (totalNetworkEdges == 0) {
return;
}
int emissionDuration = layer.getEndingTime() - layer.getStartingTime();
int totalVehiclesToEmit = layer.getVehiclesPerSecond() * emissionDuration;
// For each vehicle
for (int i = 0; i < totalVehiclesToEmit; i++) {
// Get the vehicle's type based on the user selection
VehicleType vehicleType = layer.getVehicleSelection().getRandomType();
// Get a random edge in the network
Edge randomNetworkEdge1 = allEdges.get(r.nextInt(totalNetworkEdges));
// Get a random edge in the network
Edge randomNetworkEdge2 = allEdges.get(r.nextInt(totalNetworkEdges));
// Get a random time between the emission starting and ending time
int timeToLeave = layer.getStartingTime() + r.nextInt(layer.getEndingTime() + 1 - layer.getStartingTime());
// Add the incoming vehicle trip to the output
tripsList.add(new Trip(timeToLeave,"<tripdef id=\"" + layer.getName() + "-In-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(timeToLeave) + "\" from=\"" + randomNetworkEdge1.getId() + "\" to=\"" + randomNetworkEdge2.getId() + "\" color=\"" + color + "\" type=\"" + vehicleType.getName() + "\" />\n"));
}
}
/**
* Method that generates traffic for activity based layers
*
* @param roadNetwork
* the underlying road network
* @param projectJobTypes
* the project's job types
* @param vehicleTypes
* the layer's selected vehicle types
* @param activityBasedTrafficDefinitionElements
* list of statistical and demographic elements (traffic areas
* and schools)
* @param tripsList
* @param routesList
* @throws Exception
*/
public static void GenerateActivityBasedTraffic(RoadNetwork roadNetwork, List<JobType> projectJobTypes, TypeSelection<VehicleType> vehicleTypes, List<TrafficDefinitionElement> activityBasedTrafficDefinitionElements, SUMOInstructionList<Trip> tripsList, SUMOInstructionList<Route> routesList) throws Exception {
// Sort the traffic areas and schools into separate lists
List<TrafficArea> areas = new ArrayList<TrafficArea>();
List<School> schools = new ArrayList<School>();
for (TrafficDefinitionElement t : activityBasedTrafficDefinitionElements) {
if (t instanceof TrafficArea) {
areas.add((TrafficArea) t);
} else if (t instanceof School) {
schools.add((School) t);
}
}
// Assign addresses to schools and initialize capacities
for (School school : schools) {
school.setAvailableCapacity(school.getCapacity());
school.setClosestEdge(roadNetwork.findClosestEdge(school.getLocation()));
}
// For every job type find for every area the available work positions
// and put them in a hashtable
Hashtable<JobType, List<Pair<TrafficArea, Integer>>> workPositionsPerJobTypePerArea = new Hashtable<JobType, List<Pair<TrafficArea, Integer>>>();
for (JobType projectJobType : projectJobTypes) {
// Create a list that will hold the available work positions for
// this job type per area
List<Pair<TrafficArea, Integer>> areaPositions = new ArrayList<Pair<TrafficArea, Integer>>();
// Loop through all areas
for (TrafficArea area : areas) {
// Get the possibility for this job and this area
float areaJobPossibility = area.getWorkersJobSelection().getTypePossibility(projectJobType);
// If the possibility for this job for this area is larger than
// 0 then add the area to the list.
if (areaJobPossibility > 0) {
areaPositions.add(new Pair<TrafficArea, Integer>(area, Math.round(areaJobPossibility * area.getWorkPositions())));
}
}
// Insert the list to the hashtable
workPositionsPerJobTypePerArea.put(projectJobType, areaPositions);
}
// Variable used to assign house ids
int houseID = 0;
// Create virtual population for each traffic area
for (TrafficArea area : areas) {
// Number of people to create
int unassignedPeople = area.getPopulation();
// A list of the virtual houses that will be created at this area
List<House> areaHouses = new ArrayList<House>();
Random r = RandomNumberProvider.getRandom();
// Create area houses
while (unassignedPeople > 0) {
House house = new House(area, houseID++);
// Set the house's address
Point2D.Double houseLocation = area.getRandomPointInArea();
house.setAddress(roadNetwork.findClosestEdge(houseLocation));
house.setLocation(houseLocation);
// Create house residents
// Number of adults and children is gaussian distribution
// mith mean as specified by user and standard deviation 0.8
int houseAdults = Math.round((float) (r.nextGaussian() * 0.8 + area.getAverageAdultsPerHouse()));
if (houseAdults < 1) {
houseAdults = 1;
}
int houseChildren = cern.jet.random.Poisson.staticNextInt(area.getAverageChildrenPerHouse());
house.createAdults(houseAdults, area.getPossibilityAdultIsDriver(), area.getPossibilityAdultHasJob());
house.createChildren(houseChildren);
house.assignVehiclesToDrivers(area.getPossibilityDriverHasCar(), vehicleTypes);
// Find closest school for every child in the house based on the
// child's age and the school location and capacity
for (Child child : house.getChildren()) {
School closestAvailableSchool = FindClosestSchoolToLocation(schools, child.getSchoolType(), house.getLocation());
child.setSchool(closestAvailableSchool);
if (closestAvailableSchool != null) {
closestAvailableSchool.setAvailableCapacity(closestAvailableSchool.getAvailableCapacity() - 1);
}
}
// Add the house to the area's houses
areaHouses.add(house);
// Update helper variable
unassignedPeople -= house.getNumberOfResidents();
}
// Loop through all houses and assign jobs to all
// working adults
for (House house : areaHouses) {
// For each working adult in the house
for (Adult adult : house.getWorkingAdults()) {
// Get the adult's job based on the user's selection
JobType job = area.getResidentsJobSelection().getRandomType();
List<Pair<TrafficArea, Integer>> jobAreaPositions = workPositionsPerJobTypePerArea.get(job);
// If we have areas with available work positions
if (jobAreaPositions.size() > 0) {
// Get a random area
int i = r.nextInt(jobAreaPositions.size());
// Get a random edge in the area
Point2D.Double jobLocation = jobAreaPositions.get(i).getFirst().getRandomPointInArea();
// Assign the job to the adult
adult.setJobLocation(job, roadNetwork.findClosestEdge(jobLocation));
// If this was the last job position of this kind in
// this area
if (jobAreaPositions.get(i).getSecond() == 1) {
// Remove the area - it is full
jobAreaPositions.remove(i);
} else {
// Decrease the available work positions
jobAreaPositions.get(i).setSecond(jobAreaPositions.get(i).getSecond() - 1);
}
}
// If no available work positions exist then the adult is
// unemployed
else {
adult.setHasJob(false);
}
}
}
// Create activities for the people in each house
for (House house : areaHouses) {
System.out.println(area.getName() + " " + String.valueOf(house.getId()));
house.createActivities(tripsList, routesList);
}
}
}
/**
* Generates traffic for a {@link HotSpot}
*
* @param spot
* the hotspot for which to generate traffic
* @param roadNetwork
* the underlying road network
* @return list of generated trips
*/
private static SUMOInstructionList<Trip> GenerateHotSpotTraffic(HotSpot spot, RoadNetwork roadNetwork) {
Random r = RandomNumberProvider.getRandom();
SUMOInstructionList<Trip> trips = new SUMOInstructionList<Trip>();
// Get the edges that lie within the hotspot
List<Edge> hotspotEdges = new ArrayList<Edge>();
hotspotEdges = roadNetwork.SelectEdges(spot.getArea());
int totalHotspotEdges = hotspotEdges.size();
// Get all the edges in the road network
List<Edge> allEdges = new ArrayList<Edge>();
allEdges = roadNetwork.getEdges();
// Remove the hotspot edges
for (Edge e : hotspotEdges) {
if (allEdges.contains(e)) {
allEdges.remove(e);
}
}
int totalNetworkEdges = allEdges.size();
String color = new Float(spot.getColor().getRed() / 255f).toString() + "," + new Float(spot.getColor().getGreen() / 255f).toString() + "," + new Float(spot.getColor().getBlue() / 255f).toString();
// Simple validation
if ((totalNetworkEdges == 0) || (totalHotspotEdges == 0)) {
return null;
}
// For each vehicle
for (int i = 0; i < spot.getNumberOfVehicles(); i++) {
// Get the vehicle's type based on the user selection
VehicleType vehicleType = spot.getVehicleSelection().getRandomType();
// Get a random edge in the hotspot
Edge randomHotspotEdge = hotspotEdges.get(r.nextInt(totalHotspotEdges));
// Get a random edge in the network
Edge randomNetworkEdge = allEdges.get(r.nextInt(totalNetworkEdges));
// If the hotspot is incoming (vehicles from anywhere to the
// hotspot)
if (spot.isDirectionIn()) {
int timeOfDepartureFromSource = 0;
// If the time is specified as the time of departure from the
// source
if (spot.getDirectionInType() == HotSpot.DirectionInTimeType.TimeOfDepartureFromSource) {
// Get a random time between the incoming begin time and end
// time
timeOfDepartureFromSource = spot.getDirectionInBeginTime() + r.nextInt(spot.getDirectionInEndTime() + 1 - spot.getDirectionInBeginTime());
}
// If the time is specified as the time of arrival to the
// hotspot
else if (spot.getDirectionInType() == HotSpot.DirectionInTimeType.TimeOfArrivalToDestination) {
// Try to estimate the distance that the vehicle will need
// to travel
float distanceToTravel = randomHotspotEdge.DistanceFrom(randomNetworkEdge);
// Estimate the time needed to cover this distance
int estimatedTravelTime = (int) Math.round(distanceToTravel / Constants.averageSpeed);
// Get a random time between the incoming begin time and end
// time minus the time needed to travel
timeOfDepartureFromSource = spot.getDirectionInBeginTime() + r.nextInt(spot.getDirectionInEndTime() + 1 - spot.getDirectionInBeginTime()) - estimatedTravelTime;
// A vehicle can't start with a negative departure time
timeOfDepartureFromSource = Math.min(timeOfDepartureFromSource, 0);
}
// Add the incoming vehicle trip to the output
trips.add(new Trip(timeOfDepartureFromSource, "<tripdef id=\"" + spot.getName() + "-In-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(timeOfDepartureFromSource) + "\" from=\"" + randomNetworkEdge.getId() + "\" to=\"" + randomHotspotEdge.getId() + "\" color=\"" + color + "\" type=\"" + vehicleType.getName() + "\" />\n"));
}
// If the hotspot is outgoing (vehicles from the hotspot to
// anywhere)
if (spot.isDirectionOut()) {
// Get a random time between the outgoing begin time and end
// time
int timeToLeaveSpot = spot.getDirectionOutBeginTime() + r.nextInt(spot.getDirectionOutEndTime() + 1 - spot.getDirectionOutBeginTime());
// Add the outgoing vehicle trip to the output
trips.add(new Trip(timeToLeaveSpot, "<tripdef id=\"" + spot.getName() + "-Out-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(timeToLeaveSpot) + "\" from=\"" + randomHotspotEdge.getId() + "\" to=\"" + randomNetworkEdge.getId() + "\" color=\"" + color + "\" type=\"" + vehicleType.getName() + "\" />\n"));
}
}
return trips;
}
/**
* Generates traffic for a {@link Flow}
*
* @param flow
* the flow for which to generate traffic
* @return list of generated trips
*/
private static SUMOInstructionList<Trip> GenerateFlowTraffic(Flow flow) {
Random r = RandomNumberProvider.getRandom();
SUMOInstructionList<Trip> trips = new SUMOInstructionList<Trip>();
// For each vehicle
for (int i = 0; i < flow.getNumberOfVehicles(); i++) {
// Get a random time between the begin time and end time
int departureTime = flow.getBeginTime() + r.nextInt(flow.getEndTime() + 1 - flow.getBeginTime());
String color = new Float(flow.getColor().getRed() / 255f).toString() + "," + new Float(flow.getColor().getGreen() / 255f).toString() + "," + new Float(flow.getColor().getBlue() / 255f).toString();
// Create the trip
trips.add(new Trip(departureTime, "<tripdef id=\"" + flow.getName() + "-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(departureTime) + "\" from=\"" + flow.getStart().getId() + "\" to=\"" + flow.getEnd().getId() + "\" color=\"" + color + "\" type=\"" + flow.getVehicleSelection().getRandomType().getName() + "\" />\n"));
}
return trips;
}
/**
* Generates traffic for an {@link Accident}
*
* @param accident
* the accident for which to generate traffic
* @param roadNetwork
* the road network
* @return list of generated routes
* @throws Exception
*/
private static SUMOInstructionList<Route> GenerateAccidentTraffic(Accident accident, RoadNetwork roadNetwork) throws Exception {
// Random r = RandomNumberProvider.getRandom();
// List<Edge> networkEdges = roadNetwork.getEdges();
SUMOInstructionList<Route> routes = new SUMOInstructionList<Route>();
// For each affected lane
for (Pair<Lane, Boolean> affectedLane : accident.getAffectedLanes()) {
if (affectedLane.getSecond()) {
/*
* // Create a route for a vehicle starting at the edge that the //
* accident happens and ending at a random network edge passing //
* first through an edge connected to the lane List<Edge>
* routeEdges = new ArrayList<Edge>();
*
* routeEdges.add(accident.getEdge());
*
* if (affectedLane.getFirst().getConnectedEdges().size() > 0) {
* Edge connectedEdge =
* roadNetwork.findEdge(affectedLane.getFirst().getConnectedEdges().get(0));
*
* if (connectedEdge != null) { routeEdges.add(connectedEdge); } }
*
* routeEdges.add(networkEdges.get(r.nextInt(networkEdges.size()))); //
* Expand the route for the trip String route =
* MultipleTripExpander.ExpandTrips(routeEdges);
*/
// Create a route for a vehicle starting at the edge that the
// accident happens and ending at an edge connected to the lane
String route = accident.getEdge().getId();
if (affectedLane.getFirst().getConnectedEdges().size() > 0) {
Edge connectedEdge = roadNetwork.findEdge(affectedLane.getFirst().getConnectedEdges().get(0));
if (connectedEdge != null) {
route += " " + connectedEdge.getId();
}
}
routes.add(new Route(accident.getStartingTime(), "<vehicle id=\"Accident-" + accident.getName() + "-" + affectedLane.getFirst().getId() + "\" type=\"Default\" depart=\"" + String.valueOf(accident.getStartingTime()) + "\" color=\"1,0,0\">\n" + " <route color=\"1,0,0\">" + route + "</route>\n" + " <stop lane=\"" + affectedLane.getFirst().getId() + "\" pos=\"" + accident.getEdgeRelativeLocation() + "\" duration=\"" + String.valueOf(accident.getEndingTime() - accident.getStartingTime()) + "\"/>\n" + "</vehicle>\n"));
}
}
return routes;
}
/**
* Generates traffic for an {@link AreaFlow}
*
* @param areaFlow
* the area flow for which to generate traffic
* @param roadNetwork
* the underlying road network
* @return list of generated trips
*/
private static SUMOInstructionList<Trip> GenerateAreaFlowTraffic(AreaFlow areaFlow, RoadNetwork roadNetwork) {
Random r = RandomNumberProvider.getRandom();
SUMOInstructionList<Trip> trips = new SUMOInstructionList<Trip>();
// Get the edges belonging in the start area
List<Edge> fromAreaEdges = new ArrayList<Edge>();
fromAreaEdges = roadNetwork.SelectEdges(areaFlow.getStartArea());
int totalFromAreaEdges = fromAreaEdges.size();
// Get the edges belonging in the end area
List<Edge> toAreaEdges = new ArrayList<Edge>();
toAreaEdges = roadNetwork.SelectEdges(areaFlow.getEndArea());
int totalToAreaEdges = toAreaEdges.size();
// Simple validation
if ((totalToAreaEdges == 0) || (totalFromAreaEdges == 0)) {
return null;
}
// For each vehicle
for (int i = 0; i < areaFlow.getNumberOfVehicles(); i++) {
// Get a random source and destination edge
Edge randomFromEdge = fromAreaEdges.get(r.nextInt(totalFromAreaEdges));
Edge randomToEdge = toAreaEdges.get(r.nextInt(totalToAreaEdges));
// Get a random time between the begin time and end time
int departureTime = areaFlow.getBeginTime() + r.nextInt(areaFlow.getEndTime() + 1 - areaFlow.getBeginTime());
String color = new Float(areaFlow.getColor().getRed() / 255f).toString() + "," + new Float(areaFlow.getColor().getGreen() / 255f).toString() + "," + new Float(areaFlow.getColor().getBlue() / 255f).toString();
// Create the trip
trips.add(new Trip(departureTime, "<tripdef id=\"" + areaFlow.getName() + "-" + String.valueOf(i) + "\" depart=\"" + String.valueOf(departureTime) + "\" from=\"" + randomFromEdge.getId() + "\" to=\"" + randomToEdge.getId() + "\" color=\"" + color + "\" type=\"" + areaFlow.getVehicleSelection().getRandomType().getName() + "\" />\n"));
}
return trips;
}
/**
* Finds the closest school of the specified type to a location
*
* @param schools
* the set of schools to search
* @param type
* the type of the school to find
* @param location
* the location to search near for
* @return the closest school near the specified location
*/
private static School FindClosestSchoolToLocation(List<School> schools, SchoolType type, Point2D.Double location) {
School closestSchool = null;
double minimumSchoolDistance = Float.MAX_VALUE;
// Loop through all schools
for (School school : schools) {
if ((school.getSchoolType() == type) && (school.getAvailableCapacity() > 0)) {
// Get the distance between the school and the location
double schoolDistance = school.getLocation().distance(location);
// If it is smaller than all previous distances
if (schoolDistance < minimumSchoolDistance) {
minimumSchoolDistance = schoolDistance;
closestSchool = school;
}
}
}
return closestSchool;
}
}
>>>>>>> origin/abdalla