MATSIM
PopulationReaderMatsimV5.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * *
4  * *********************************************************************** *
5  * *
6  * copyright : (C) 2011 by the members listed in the COPYING, *
7  * LICENSE and WARRANTY file. *
8  * email : info at matsim dot org *
9  * *
10  * *********************************************************************** *
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * See also COPYING, LICENSE and WARRANTY file *
17  * *
18  * *********************************************************************** */
19 
20 package org.matsim.core.population.io;
21 
22 import java.util.ArrayList;
23 import java.util.Stack;
24 
25 import org.matsim.api.core.v01.Coord;
26 import org.matsim.api.core.v01.Id;
27 import org.matsim.api.core.v01.Scenario;
45 import org.matsim.core.utils.misc.Time;
47 import org.matsim.vehicles.Vehicle;
48 import org.xml.sax.Attributes;
49 
56 /* deliberately package */ class PopulationReaderMatsimV5 extends MatsimXmlParser implements MatsimReader {
57 
58  private final static String POPULATION = "population";
59  private final static String PERSON = "person";
60  private final static String PLAN = "plan";
61  private final static String ACT = "act";
62  private final static String LEG = "leg";
63  private final static String ROUTE = "route";
64 
65  private final static String ATTR_POPULATION_DESC = "desc";
66  private final static String ATTR_PERSON_ID = "id";
67  private final static String ATTR_PERSON_SEX = "sex";
68  private final static String ATTR_PERSON_AGE = "age";
69  private final static String ATTR_PERSON_LICENSE = "license";
70  private final static String ATTR_PERSON_CARAVAIL = "car_avail";
71  private final static String ATTR_PERSON_EMPLOYED = "employed";
72  private final static String ATTR_PLAN_SCORE = "score";
73  private final static String ATTR_PLAN_TYPE = "type";
74  private final static String ATTR_PLAN_SELECTED = "selected";
75  private final static String ATTR_ACT_TYPE = "type";
76  private final static String ATTR_ACT_X = "x";
77  private final static String ATTR_ACT_Y = "y";
78  private final static String ATTR_ACT_LINK = "link";
79  private final static String ATTR_ACT_FACILITY = "facility";
80  private final static String ATTR_ACT_STARTTIME = "start_time";
81  private final static String ATTR_ACT_ENDTIME = "end_time";
82  private final static String ATTR_ACT_MAXDUR = "max_dur";
83  private final static String ATTR_LEG_MODE = "mode";
84  private final static String ATTR_LEG_DEPTIME = "dep_time";
85  private final static String ATTR_LEG_TRAVTIME = "trav_time";
86 // private final static String ATTR_LEG_ARRTIME = "arr_time";
87  private static final String ATTR_ROUTE_STARTLINK = "start_link";
88  private static final String ATTR_ROUTE_ENDLINK = "end_link";
89 
90  private final static String VALUE_YES = "yes";
91  private final static String VALUE_NO = "no";
92  private final static String VALUE_UNDEF = "undef";
93 
94  private final CoordinateTransformation coordinateTransformation;
95 
96  private final Scenario scenario;
97  private final Population plans;
98 
99  private Person currperson = null;
100  private Plan currplan = null;
101  private Activity curract = null;
102  private Leg currleg = null;
103  private Route currRoute = null;
104  private String routeDescription = null;
105 
106  private Activity prevAct = null;
107 
108  PopulationReaderMatsimV5(final Scenario scenario) {
109  this( new IdentityTransformation() , scenario );
110  }
111 
112  PopulationReaderMatsimV5(
113  final CoordinateTransformation coordinateTransformation,
114  final Scenario scenario) {
115  super(ValidationType.DTD_ONLY);
116  this.coordinateTransformation = coordinateTransformation;
117  this.scenario = scenario;
118  this.plans = scenario.getPopulation();
119  }
120 
121  @Override
122  public void startTag(final String name, final Attributes atts, final Stack<String> context) {
123  if (POPULATION.equals(name)) {
124  startPopulation(atts);
125  } else if (PERSON.equals(name)) {
126  startPerson(atts);
127  } else if (PLAN.equals(name)) {
128  startPlan(atts);
129  } else if (ACT.equals(name)) {
130  startAct(atts);
131  } else if (LEG.equals(name)) {
132  startLeg(atts);
133  } else if (ROUTE.equals(name)) {
134  startRoute(atts);
135  } else {
136  throw new RuntimeException(this + "[tag=" + name + " not known or not supported]");
137  }
138  }
139 
140  @Override
141  public void endTag(final String name, final String content, final Stack<String> context) {
142  if (PERSON.equals(name)) {
143  this.plans.addPerson(this.currperson);
144  this.currperson = null;
145  } else if (PLAN.equals(name)) {
146  if (this.currplan.getPlanElements() instanceof ArrayList<?>) {
147  ((ArrayList<?>) this.currplan.getPlanElements()).trimToSize();
148  }
149  this.currplan = null;
150  } else if (ACT.equals(name)) {
151  this.prevAct = this.curract;
152  this.curract = null;
153  } else if (ROUTE.equals(name)) {
154  endRoute(content);
155  }
156  }
157 
158  private void startPopulation(final Attributes atts) {
159  this.plans.setName(atts.getValue(ATTR_POPULATION_DESC));
160  }
161 
162  private void startPerson(final Attributes atts) {
163  String ageString = atts.getValue(ATTR_PERSON_AGE);
164 // int age = Integer.MIN_VALUE;
165  Integer age = null ;
166  if (ageString != null)
167  age = Integer.parseInt(ageString);
168  this.currperson = PopulationUtils.getFactory().createPerson(Id.create(atts.getValue(ATTR_PERSON_ID), Person.class));
169  PersonUtils.setSex(this.currperson, atts.getValue(ATTR_PERSON_SEX));
170  PersonUtils.setAge(this.currperson, age);
171  PersonUtils.setLicence(this.currperson, atts.getValue(ATTR_PERSON_LICENSE));
172  PersonUtils.setCarAvail(this.currperson, atts.getValue(ATTR_PERSON_CARAVAIL));
173  String employed = atts.getValue(ATTR_PERSON_EMPLOYED);
174  if (employed == null) {
175  PersonUtils.setEmployed(this.currperson, null);
176  } else {
177  PersonUtils.setEmployed(this.currperson, VALUE_YES.equals(employed));
178  }
179  }
180 
181  private void startPlan(final Attributes atts) {
182  String sel = atts.getValue(ATTR_PLAN_SELECTED);
183  boolean selected;
184  if (VALUE_YES.equals(sel)) {
185  selected = true;
186  }
187  else if (VALUE_NO.equals(sel)) {
188  selected = false;
189  }
190  else {
191  throw new IllegalArgumentException(
192  "Attribute 'selected' of Element 'Plan' is neither 'yes' nor 'no'.");
193  }
194  this.routeDescription = null;
195  this.currplan = PersonUtils.createAndAddPlan(this.currperson, selected);
196 
197  String scoreString = atts.getValue(ATTR_PLAN_SCORE);
198  if (scoreString != null) {
199  double score = Double.parseDouble(scoreString);
200  this.currplan.setScore(score);
201  }
202 
203  String type = atts.getValue(ATTR_PLAN_TYPE);
204  if (type != null) {
205  this.currplan.setType(type);
206  }
207  }
208 
209  private void startAct(final Attributes atts) {
210  if (atts.getValue(ATTR_ACT_LINK) != null) {
211  Id<Link> linkId1 = Id.create(atts.getValue(ATTR_ACT_LINK), Link.class);
212  this.curract = PopulationUtils.createAndAddActivityFromLinkId(this.currplan, atts.getValue(ATTR_ACT_TYPE), linkId1);
213  if ((atts.getValue(ATTR_ACT_X) != null) && (atts.getValue(ATTR_ACT_Y) != null)) {
214  final Coord coord = parseCoord( atts );
215  this.curract.setCoord(coord);
216  }
217  } else if ((atts.getValue(ATTR_ACT_X) != null) && (atts.getValue(ATTR_ACT_Y) != null)) {
218  final Coord coord = parseCoord( atts );
219  this.curract = PopulationUtils.createAndAddActivityFromCoord(this.currplan, atts.getValue(ATTR_ACT_TYPE), coord);
220  } else {
221  throw new IllegalArgumentException("In this version of MATSim either the coords or the link must be specified for an Act.");
222  }
223  Time.parseOptionalTime(atts.getValue(ATTR_ACT_STARTTIME))
224  .ifDefinedOrElse(curract::setStartTime, curract::setStartTimeUndefined);
225  Time.parseOptionalTime(atts.getValue(ATTR_ACT_MAXDUR))
226  .ifDefinedOrElse(curract::setMaximumDuration, curract::setMaximumDurationUndefined);
227  Time.parseOptionalTime(atts.getValue(ATTR_ACT_ENDTIME))
228  .ifDefinedOrElse(curract::setEndTime, curract::setEndTimeUndefined);
229  String fId = atts.getValue(ATTR_ACT_FACILITY);
230  if (fId != null) {
231  this.curract.setFacilityId(Id.create(fId, ActivityFacility.class));
232  }
233  if (this.routeDescription != null) {
234  finishLastRoute();
235  }
236  }
237 
238  private Coord parseCoord(Attributes atts) {
239  return this.coordinateTransformation.transform(
240  new Coord(
241  Double.parseDouble(atts.getValue( ATTR_ACT_X )),
242  Double.parseDouble(atts.getValue( ATTR_ACT_Y )) ) );
243  }
244 
245  private void finishLastRoute() {
246  Id<Link> startLinkId = null;
247  if (this.currRoute.getStartLinkId() != null) {
248  startLinkId = this.currRoute.getStartLinkId();
249  } else if (this.prevAct.getLinkId() != null) {
250  startLinkId = this.prevAct.getLinkId();
251  }
252  Id<Link> endLinkId = null;
253  if (this.currRoute.getEndLinkId() != null) {
254  endLinkId = this.currRoute.getEndLinkId();
255  } else if (this.curract != null && this.curract.getLinkId() != null) {
256  endLinkId = this.curract.getLinkId();
257  }
258 
259  this.currRoute.setStartLinkId(startLinkId);
260  this.currRoute.setEndLinkId(endLinkId);
261  this.currRoute.setRouteDescription(this.routeDescription.trim());
262  if (Double.isNaN(this.currRoute.getDistance())) {
263  if (this.currRoute instanceof NetworkRoute) {
264  if (!this.scenario.getNetwork().getLinks().isEmpty()) {
265  this.currRoute.setDistance(RouteUtils.calcDistanceExcludingStartEndLink((NetworkRoute) this.currRoute, this.scenario.getNetwork()));
266  }
267  } else {
268  Coord fromCoord = getCoord(this.prevAct);
269  Coord toCoord = getCoord(this.curract);
270  if (fromCoord != null && toCoord != null) {
271  double dist = CoordUtils.calcEuclideanDistance(fromCoord, toCoord);
272  if ( this.scenario.getConfig().routing().
273  getModeRoutingParams().containsKey( this.currleg.getMode() ) ) {
274  double estimatedNetworkDistance = dist * this.scenario.getConfig().routing().
275  getModeRoutingParams().get( this.currleg.getMode() ).getBeelineDistanceFactor() ;
276  this.currRoute.setDistance(estimatedNetworkDistance);
277  }
278  }
279  }
280  }
281  if (this.currRoute.getTravelTime().isUndefined()) {
282  this.currleg.getTravelTime().ifDefined(this.currRoute::setTravelTime);
283  }
284 
285  this.routeDescription = null;
286  this.currRoute = null;
287 
288  }
289 
290  private Coord getCoord(Activity activity) {
291  if (activity == null) {
292  return null;
293  }
294  Coord fromCoord;
295  if (activity.getCoord() != null) {
296  fromCoord = activity.getCoord();
297  } else {
298  if (!this.scenario.getNetwork().getLinks().isEmpty()) {
299  fromCoord = this.scenario.getNetwork().getLinks().get(activity.getLinkId()).getCoord();
300  } else {
301  fromCoord = null;
302  }
303  }
304  return fromCoord;
305  }
306 
307  private void startLeg(final Attributes atts) {
308  if (this.routeDescription != null) {
309  finishLastRoute();
310  }
311 
312  String mode = atts.getValue(ATTR_LEG_MODE);
313  if (VALUE_UNDEF.equals(mode)) {
314  mode = "undefined";
315  }
316  this.currleg = PopulationUtils.createAndAddLeg( this.currplan, mode.intern() );
317  Time.parseOptionalTime(atts.getValue(ATTR_LEG_DEPTIME))
318  .ifDefinedOrElse(currleg::setDepartureTime, currleg::setDepartureTimeUndefined);
319  Time.parseOptionalTime(atts.getValue(ATTR_LEG_TRAVTIME))
320  .ifDefinedOrElse(currleg::setTravelTime, currleg::setTravelTimeUndefined);
321 // LegImpl r = this.currleg;
322 // r.setTravelTime( Time.parseTime(atts.getValue(ATTR_LEG_ARRTIME)) - r.getDepartureTime() );
323  // arrival time is in dtd, but no longer evaluated in code (according to not being in API). kai, jun'16
324  }
325 
326  private void startRoute(final Attributes atts) {
327  String startLinkId = atts.getValue(ATTR_ROUTE_STARTLINK);
328  String endLinkId = atts.getValue(ATTR_ROUTE_ENDLINK);
329  String routeType = atts.getValue("type");
330 
331  if (routeType == null) {
332  String legMode = this.currleg.getMode();
333  if ("pt".equals(legMode)) {
334  routeType = "experimentalPt1";
335  } else if ("car".equals(legMode)) {
336  routeType = "links";
337  } else {
338  routeType = "generic";
339  }
340  }
341 
342  RouteFactories factory = this.scenario.getPopulation().getFactory().getRouteFactories();
343  Class<? extends Route> routeClass = factory.getRouteClassForType(routeType);
344 
345  this.currRoute = this.scenario.getPopulation().getFactory().getRouteFactories().createRoute(routeClass, startLinkId == null ? null : Id.create(startLinkId, Link.class), endLinkId == null ? null : Id.create(endLinkId, Link.class));
346  this.currleg.setRoute(this.currRoute);
347 
348  if (atts.getValue("trav_time") != null) {
349  Time.parseOptionalTime(atts.getValue("trav_time"))
350  .ifDefinedOrElse(currRoute::setTravelTime, currRoute::setTravelTimeUndefined);
351  }
352  if (atts.getValue("distance") != null) {
353  this.currRoute.setDistance(Double.parseDouble(atts.getValue("distance")));
354  }
355  if (atts.getValue("vehicleRefId") != null && this.currRoute instanceof NetworkRoute ) {
356  ((NetworkRoute)this.currRoute).setVehicleId(Id.create(atts.getValue("vehicleRefId"), Vehicle.class));
357  }
358  }
359 
360  private void endRoute(final String content) {
361  this.routeDescription = content;
362 
363  Id<Link> startLinkId = this.currRoute.getStartLinkId();
364  Id<Link> endLinkId = this.currRoute.getEndLinkId();
365  this.currRoute.setStartLinkId(startLinkId);
366  this.currRoute.setEndLinkId(endLinkId);
367  this.currRoute.setRouteDescription(this.routeDescription.trim());
368 
369  if (Double.isNaN(this.currRoute.getDistance())) {
370  if (this.currRoute instanceof NetworkRoute) {
371  if (!this.scenario.getNetwork().getLinks().isEmpty()) {
372  this.currRoute.setDistance(RouteUtils.calcDistanceExcludingStartEndLink((NetworkRoute) this.currRoute, this.scenario.getNetwork()));
373  }
374  } else {
375  Coord fromCoord = getCoord(this.prevAct);
376  Coord toCoord = getCoord(this.curract);
377  if (fromCoord != null && toCoord != null) {
378  double dist = CoordUtils.calcEuclideanDistance(fromCoord, toCoord);
379  if ( this.scenario.getConfig().routing().
380  getModeRoutingParams().containsKey( this.currleg.getMode() ) ) {
381  double estimatedNetworkDistance = dist * this.scenario.getConfig().routing().
382  getModeRoutingParams().get( this.currleg.getMode() ).getBeelineDistanceFactor() ;
383  this.currRoute.setDistance(estimatedNetworkDistance);
384  }
385  }
386  }
387  }
388  if (this.currRoute.getTravelTime().isUndefined()) {
389  this.currleg.getTravelTime().ifDefined(this.currRoute::setTravelTime);
390  }
391 
392  if (this.currRoute.getEndLinkId() != null) {
393  // this route is complete
394  this.currRoute = null;
395  this.routeDescription = null;
396  }
397  }
398 
399 }
abstract void startTag(String name, Attributes atts, Stack< String > context)