Package simulation

Source Code of simulation.TrafficGenerator

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,"<trip 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, "<trip 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, "<trip 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, "<trip 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, "<trip 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;
  }
}
TOP

Related Classes of simulation.TrafficGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.