20 package org.matsim.core.population.io;
22 import java.util.ArrayList;
23 import java.util.Stack;
48 import org.xml.sax.Attributes;
56 class PopulationReaderMatsimV5
extends MatsimXmlParser implements MatsimReader {
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";
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";
87 private static final String ATTR_ROUTE_STARTLINK =
"start_link";
88 private static final String ATTR_ROUTE_ENDLINK =
"end_link";
90 private final static String VALUE_YES =
"yes";
91 private final static String VALUE_NO =
"no";
92 private final static String VALUE_UNDEF =
"undef";
94 private final CoordinateTransformation coordinateTransformation;
96 private final Scenario scenario;
97 private final Population plans;
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;
106 private Activity prevAct = null;
108 PopulationReaderMatsimV5(
final Scenario scenario) {
109 this(
new IdentityTransformation() , scenario );
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();
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)) {
127 }
else if (PLAN.equals(name)) {
129 }
else if (ACT.equals(name)) {
131 }
else if (LEG.equals(name)) {
133 }
else if (ROUTE.equals(name)) {
136 throw new RuntimeException(
this +
"[tag=" + name +
" not known or not supported]");
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();
149 this.currplan = null;
150 }
else if (ACT.equals(name)) {
151 this.prevAct = this.curract;
153 }
else if (ROUTE.equals(name)) {
158 private void startPopulation(
final Attributes atts) {
159 this.plans.setName(atts.getValue(ATTR_POPULATION_DESC));
162 private void startPerson(
final Attributes atts) {
163 String ageString = atts.getValue(ATTR_PERSON_AGE);
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);
177 PersonUtils.setEmployed(this.currperson, VALUE_YES.equals(employed));
181 private void startPlan(
final Attributes atts) {
182 String sel = atts.getValue(ATTR_PLAN_SELECTED);
184 if (VALUE_YES.equals(sel)) {
187 else if (VALUE_NO.equals(sel)) {
191 throw new IllegalArgumentException(
192 "Attribute 'selected' of Element 'Plan' is neither 'yes' nor 'no'.");
194 this.routeDescription = null;
195 this.currplan = PersonUtils.createAndAddPlan(this.currperson, selected);
197 String scoreString = atts.getValue(ATTR_PLAN_SCORE);
198 if (scoreString != null) {
199 double score = Double.parseDouble(scoreString);
200 this.currplan.setScore(score);
203 String type = atts.getValue(ATTR_PLAN_TYPE);
205 this.currplan.setType(type);
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);
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);
221 throw new IllegalArgumentException(
"In this version of MATSim either the coords or the link must be specified for an Act.");
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);
231 this.curract.setFacilityId(Id.create(fId, ActivityFacility.class));
233 if (this.routeDescription != null) {
238 private Coord parseCoord(Attributes atts) {
239 return this.coordinateTransformation.transform(
241 Double.parseDouble(atts.getValue( ATTR_ACT_X )),
242 Double.parseDouble(atts.getValue( ATTR_ACT_Y )) ) );
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();
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();
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()));
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);
281 if (this.currRoute.getTravelTime().isUndefined()) {
282 this.currleg.getTravelTime().ifDefined(this.currRoute::setTravelTime);
285 this.routeDescription = null;
286 this.currRoute = null;
290 private Coord getCoord(Activity activity) {
291 if (activity == null) {
295 if (activity.getCoord() != null) {
296 fromCoord = activity.getCoord();
298 if (!this.scenario.getNetwork().getLinks().isEmpty()) {
299 fromCoord = this.scenario.getNetwork().getLinks().get(activity.getLinkId()).getCoord();
307 private void startLeg(
final Attributes atts) {
308 if (this.routeDescription != null) {
312 String mode = atts.getValue(ATTR_LEG_MODE);
313 if (VALUE_UNDEF.equals(mode)) {
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);
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");
331 if (routeType == null) {
332 String legMode = this.currleg.getMode();
333 if (
"pt".equals(legMode)) {
334 routeType =
"experimentalPt1";
335 }
else if (
"car".equals(legMode)) {
338 routeType =
"generic";
342 RouteFactories factory = this.scenario.getPopulation().getFactory().getRouteFactories();
343 Class<? extends Route> routeClass = factory.getRouteClassForType(routeType);
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);
348 if (atts.getValue(
"trav_time") != null) {
349 Time.parseOptionalTime(atts.getValue(
"trav_time"))
350 .ifDefinedOrElse(currRoute::setTravelTime, currRoute::setTravelTimeUndefined);
352 if (atts.getValue(
"distance") != null) {
353 this.currRoute.setDistance(Double.parseDouble(atts.getValue(
"distance")));
355 if (atts.getValue(
"vehicleRefId") != null && this.currRoute instanceof NetworkRoute ) {
356 ((NetworkRoute)this.currRoute).setVehicleId(Id.create(atts.getValue(
"vehicleRefId"), Vehicle.class));
360 private void endRoute(
final String content) {
361 this.routeDescription = content;
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());
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()));
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);
388 if (this.currRoute.getTravelTime().isUndefined()) {
389 this.currleg.getTravelTime().ifDefined(this.currRoute::setTravelTime);
392 if (this.currRoute.getEndLinkId() != null) {
394 this.currRoute = null;
395 this.routeDescription = null;
abstract void startTag(String name, Attributes atts, Stack< String > context)