MATSIM
CreatePopulation.java
Go to the documentation of this file.
1 package tutorial.programming.demandGenerationWithFacilities;
2 
3 
4 import java.io.BufferedReader;
5 import java.io.FileReader;
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.Map;
9 import java.util.Random;
10 import java.util.TreeMap;
11 
12 import org.apache.log4j.Logger;
13 import org.matsim.api.core.v01.Coord;
14 import org.matsim.api.core.v01.Id;
15 import org.matsim.api.core.v01.Scenario;
20 import org.matsim.core.utils.collections.QuadTree;
23 
24 
25 class CreatePopulation {
26 
27  private Scenario scenario;
28 
29  // [[ 0 ]] here you have to fill in the path of the census file
30  private static final String censusFile = "examples/tutorial/programming/demandGenerationWithFacilities/census.txt";
31  private static final String municipalitiesFile = "examples/tutorial/programming/demandGenerationWithFacilities/swiss_municipalities.txt";
32 
33  private QuadTree<ActivityFacility> homeFacilitiesTree;
34  private QuadTree<ActivityFacility> workFacilitiesTree;
35 
36  private TreeMap<String, Coord> municipalityCentroids = new TreeMap<>();
37  private Random random = new Random(3838494);
38 
39  private ObjectAttributes personHomeAndWorkLocations = new ObjectAttributes();
40  private final static Logger log = Logger.getLogger(CreatePopulation.class);
41 
42  // --------------------------------------------------------------------------
43 
44  public void run(Scenario scenario1) {
45  this.scenario = scenario1;
46  this.init();
47  this.populationCreation();
48  }
49 
50  private void init() {
51  /*
52  * Build quad trees for assigning home and work locations
53  */
54  this.homeFacilitiesTree = CreatePopulation.createActivitiesTree("home", this.scenario);
55  this.workFacilitiesTree = CreatePopulation.createActivitiesTree("work", this.scenario);
56 
57  this.readMunicipalities();
58  }
59 
60  private void populationCreation() {
61  /*
62  * For convenience and code readability store population and population factory in a local variable
63  */
64  Population population = this.scenario.getPopulation();
65  PopulationFactory populationFactory = population.getFactory();
66 
67  /*
68  * Read the census file
69  * Create the persons and add the socio-demographics
70  */
71  try
72  ( BufferedReader bufferedReader = new BufferedReader(new FileReader(CreatePopulation.censusFile)) )
73  {
74  String line = bufferedReader.readLine(); //skip header
75 
76  int index_personId = 4;
77  int index_age = 6;
78  int index_workLocation = 8;
79  int index_xHomeCoord = 10;
80  int index_yHomeCoord = 11;
81 
82  while ((line = bufferedReader.readLine()) != null) {
83  String parts[] = line.split("\t");
84 
85  /*
86  * Create a person and add it to the population
87  */
88  Person person = populationFactory.createPerson(Id.create(parts[index_personId], Person.class));
89 
90  person.getCustomAttributes().put(PersonUtils.AGE, Integer.parseInt(parts[index_age]));
91 
92  boolean employed = true;
93  if (parts[index_workLocation].equals("-1")) employed = false;
94  final Boolean employed1 = employed;
95  person.getCustomAttributes().put(PersonUtils.EMPLOYED, employed1);
96 
97  population.addPerson(person);
98 
99  /*
100  * Assign a home location and buffer it somewhere
101  * This could also be done in the persons knowledge. But we use ObjectAttributes here.
102  * Try to understand what is happening here [[ 2 ]]
103  */
104  Coord homeCoord = new Coord(Double.parseDouble(parts[index_xHomeCoord]), Double.parseDouble(parts[index_yHomeCoord]));
105  ActivityFacility homeFacility = this.homeFacilitiesTree.getClosest(homeCoord.getX(), homeCoord.getY());
106  if (homeFacility == null) {
107  throw new RuntimeException();
108  }
109  personHomeAndWorkLocations.putAttribute(person.getId().toString(), "home", homeFacility);
110 
111  if (employed) {
112  /*
113  * Assign a work location and buffer it somewhere.
114  * This could also be done in the persons knowledge. But we use ObjectAttributes here.
115  */
116  String municipalityId = parts[index_workLocation];
117  ActivityFacility workFacility = this.getWorkFacility(municipalityId);
118  personHomeAndWorkLocations.putAttribute(person.getId().toString(), "work", workFacility);
119  }
120  }
121  bufferedReader.close();
122 
123  } // end try
124  catch (IOException e) {
125  e.printStackTrace();
126  }
127  }
128 
129  private void readMunicipalities() {
130  try {
131  BufferedReader bufferedReader = new BufferedReader(new FileReader(CreatePopulation.municipalitiesFile));
132  String line = bufferedReader.readLine(); //skip header
133 
134  while ((line = bufferedReader.readLine()) != null) {
135  String parts[] = line.split("\t");
136 
137  String id = parts[0];
138  /*
139  * COORD: pay attention to coordinate systems!
140  */
141  Coord coord = new Coord(Double.parseDouble(parts[1]), Double.parseDouble(parts[2]));
142  this.municipalityCentroids.put(id, coord);;
143  }
144  bufferedReader.close();
145 
146  } catch (IOException e) {
147  throw new RuntimeException(e);
148  }
149  }
150 
151  private ActivityFacility getWorkFacility(String municipalityId) {
152  Coord coord = this.municipalityCentroids.get(municipalityId);
153  ArrayList<ActivityFacility> list =
154  (ArrayList<ActivityFacility>) this.workFacilitiesTree.getDisk(coord.getX(), coord.getY(), 8000);
155 
156  // pick a facility randomly from this list
157  // TODO: check range of randomIndex. Is last element of list ever chosen?
158  int randomIndex = (int)(random.nextFloat() * (list.size() - 1));
159  return list.get(randomIndex);
160  }
161 
162  public Scenario getScenario() {
163  return scenario;
164  }
165 
166  public ObjectAttributes getPersonHomeAndWorkLocations() {
167  return personHomeAndWorkLocations;
168  }
169 
170  static QuadTree<ActivityFacility> createActivitiesTree(String activityType, Scenario scenario) {
171  QuadTree<ActivityFacility> facQuadTree = CreatePopulation.builFacQuadTree(activityType, scenario.getActivityFacilities().getFacilitiesForActivityType(activityType));
172  return facQuadTree;
173  }
174 
175  private static QuadTree<ActivityFacility> builFacQuadTree(String type, Map<Id<ActivityFacility>, ? extends ActivityFacility> facilities_of_type) {
176  log.info(" building " + type + " facility quad tree");
177  double minx = Double.POSITIVE_INFINITY;
178  double miny = Double.POSITIVE_INFINITY;
179  double maxx = Double.NEGATIVE_INFINITY;
180  double maxy = Double.NEGATIVE_INFINITY;
181 
182  for (final ActivityFacility f : facilities_of_type.values()) {
183  if (f.getCoord().getX() < minx) { minx = f.getCoord().getX(); }
184  if (f.getCoord().getY() < miny) { miny = f.getCoord().getY(); }
185  if (f.getCoord().getX() > maxx) { maxx = f.getCoord().getX(); }
186  if (f.getCoord().getY() > maxy) { maxy = f.getCoord().getY(); }
187  }
188  minx -= 1.0;
189  miny -= 1.0;
190  maxx += 1.0;
191  maxy += 1.0;
192  System.out.println(" xrange(" + minx + "," + maxx + "); yrange(" + miny + "," + maxy + ")");
193  QuadTree<ActivityFacility> quadtree = new QuadTree<ActivityFacility>(minx, miny, maxx, maxy);
194  for (final ActivityFacility f : facilities_of_type.values()) {
195  quadtree.put(f.getCoord().getX(),f.getCoord().getY(),f);
196  }
197  log.info("Quadtree size: " + quadtree.size());
198  return quadtree;
199  }
200 }