MATSIM
StreamingPopulationWriter.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * PlansWriter.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007, 2012 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.population.io;
22 
23 import org.apache.logging.log4j.LogManager;
24 import org.apache.logging.log4j.Logger;
25 import org.matsim.api.core.v01.Id;
38 
39 import java.io.BufferedWriter;
40 import java.io.IOException;
41 import java.io.UncheckedIOException;
42 import java.util.HashMap;
43 import java.util.Map;
44 
45 public final class StreamingPopulationWriter implements PersonAlgorithm {
46  private final static Logger log = LogManager.getLogger(StreamingPopulationWriter.class);
47 
48  private final double write_person_fraction;
49 
51  private Counter counter = new Counter("[" + this.getClass().getSimpleName() + "] dumped person # ");
52  private final Map<Class<?>, AttributeConverter<?>> attributeConverters = new HashMap<>();
53 
54  private static class DummyMatsimWriter extends AbstractMatsimWriter {
55  BufferedWriter getWriter() {
56  return writer;
57  }
58  void openHere(String filename ) {
59  super.openFile(filename);
60  }
61  void closeHere() {
62  super.close() ;
63  }
64  }
66 
67 
69  this(1.0);
70  }
71 
73  final CoordinateTransformation coordinateTransformation) {
74  this(coordinateTransformation , 1.0);
75  }
76 
83  final CoordinateTransformation coordinateTransformation,
84  final double fraction) {
85  this.write_person_fraction = fraction;
86  this.handler = new ParallelPopulationWriterHandlerV6(coordinateTransformation);
87  }
88 
93  final double fraction) {
94  this( new IdentityTransformation() , fraction );
95  }
96 
97  public <T> void putAttributeConverter(Class<T> clazz, AttributeConverter<T> converter) {
98  this.attributeConverters.put(clazz, converter);
99  }
100 
101  public void putAttributeConverters(final Map<Class<?>, AttributeConverter<?>> converters) {
102  this.attributeConverters.putAll(converters);
103  }
104 
105  // implementation of PersonAlgorithm
106  // this is primarily to use the PlansWriter with filters and other algorithms.
107  public final void startStreaming(final String filename) {
108 // if ((this.population instanceof Population) && (((Population) this.population).isStreaming())) {
109 // if ( this.population instanceof StreamingPopulationReader.StreamingPopulation ) {
110  // write the file head if it is used with streaming.
111  writeStartPlans(filename);
112 // } else {
113 // log.error("Cannot start streaming. Streaming must be activated in the Population.");
114 // }
115  }
116 
117  @Override
118  public final void run(final Person person) {
119  writePerson(person);
120  }
121 
122  public final void closeStreaming() {
123 // if ((this.population instanceof Population) && (((Population) this.population).isStreaming())) {
124 // if ( this.population instanceof StreamingPopulationReader.StreamingPopulation ) {
125  if (matsimWriter.getWriter() != null) {
126  writeEndPlans();
127  } else {
128  log.error("Cannot close streaming. File is not open.");
129  }
130 // } else {
131 // log.error("Cannot close streaming. Streaming must be activated in the Population.");
132 // }
133  }
134 
135  public final void writeStartPlans(final String filename) {
136  Population fakepop = new Population(){
137 
138  @Override public PopulationFactory getFactory() {
139  throw new RuntimeException("not implemented") ;
140  }
141  @Override public String getName() {
142  return "population written from streaming" ;
143  }
144  @Override public void setName(String name) {
145  throw new RuntimeException("not implemented") ;
146  }
147  @Override public Map<Id<Person>, ? extends Person> getPersons() {
148  throw new RuntimeException("not implemented") ;
149  }
150  @Override public void addPerson(Person p) {
151  throw new RuntimeException("not implemented") ;
152  }
153  @Override public Person removePerson(Id<Person> personId) {
154  throw new RuntimeException("not implemented") ;
155  }
156  @Override
157  public Attributes getAttributes() {
158  //A stream written Population cannot contain Population Attributes, only Person Attributes.
159  return new AttributesImpl();
160  }
161 
162  } ;
163  try {
164  matsimWriter.openHere(filename);
165  this.handler.putAttributeConverters(this.attributeConverters);
166  this.handler.writeHeaderAndStartElement(matsimWriter.getWriter());
167  this.handler.startPlans(fakepop, matsimWriter.getWriter());
168  this.handler.writeSeparator(matsimWriter.getWriter());
169  } catch (IOException e) {
170  throw new UncheckedIOException(e);
171  }
172  }
173 
174  @Deprecated // see comments in method. kai, dec'16
175  public final void writePersons() {
176  throw new RuntimeException("this execution path does not longer exist. See comments in code") ;
177  // you can program this yourself by using something like
178 // for (Person p : PopulationUtils.getSortedPersons(population).values()) {
179 // writePerson(p);
180 // }
181  // providing it at the level here would mean to have access to a population that is otherwise totally not needed for streaming.
182  // kai, dec'16
183  }
184 
185  public final void writePerson(final Person person) {
186  try {
187  if ((this.write_person_fraction < 1.0) && (MatsimRandom.getRandom().nextDouble() >= this.write_person_fraction)) {
188  return;
189  }
190  this.handler.writePerson(person, matsimWriter.getWriter());
191  counter.incCounter();
192  } catch (IOException e) {
193  throw new UncheckedIOException(e);
194  }
195  }
196 
197  public final void writeEndPlans() {
198  try {
199  this.handler.endPlans(matsimWriter.getWriter());
200  } catch (IOException e) {
201  throw new UncheckedIOException(e);
202  }
203  matsimWriter.closeHere();
204  }
205 
206  public final void setWriterHandler(final PopulationWriterHandler handler) {
207  this.handler = handler;
208  }
209 
210 }
void writePerson(final Person person, final BufferedWriter out)
final Map< Class<?>, AttributeConverter<?> > attributeConverters
StreamingPopulationWriter(final CoordinateTransformation coordinateTransformation, final double fraction)
default void putAttributeConverters(Map< Class<?>, AttributeConverter<?>> converters)
void startPlans(final Population plans, final BufferedWriter out)
StreamingPopulationWriter(final CoordinateTransformation coordinateTransformation)
final void setWriterHandler(final PopulationWriterHandler handler)
void putAttributeConverters(final Map< Class<?>, AttributeConverter<?>> converters)