001/* *********************************************************************** * 002 * project: org.matsim.* 003 * * 004 * *********************************************************************** * 005 * * 006 * copyright : (C) 2016 by the members listed in the COPYING, * 007 * LICENSE and WARRANTY file. * 008 * email : info at matsim dot org * 009 * * 010 * *********************************************************************** * 011 * * 012 * This program is free software; you can redistribute it and/or modify * 013 * it under the terms of the GNU General Public License as published by * 014 * the Free Software Foundation; either version 2 of the License, or * 015 * (at your option) any later version. * 016 * See also COPYING, LICENSE and WARRANTY file * 017 * * 018 * *********************************************************************** */ 019 020package org.matsim.contrib.util; 021 022import java.util.function.Function; 023 024import org.matsim.api.core.v01.Coord; 025import org.matsim.api.core.v01.Identifiable; 026import org.matsim.contrib.util.timeprofile.TimeProfiles; 027import org.matsim.core.controler.MatsimServices; 028import org.matsim.core.mobsim.framework.events.MobsimBeforeCleanupEvent; 029import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; 030import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; 031import org.matsim.core.mobsim.framework.listeners.MobsimBeforeCleanupListener; 032import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener; 033import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; 034import org.matsim.core.utils.io.IOUtils; 035 036public class XYDataCollector<T extends Identifiable<T>> 037 implements MobsimInitializedListener, MobsimBeforeSimStepListener, MobsimBeforeCleanupListener { 038 public interface XYDataCalculator<T> { 039 String[] getHeader(); 040 041 Coord getCoord(T object); 042 043 Object[] calculate(T object); 044 } 045 046 private final Iterable<T> monitoredObjects; 047 private final XYDataCalculator<T> calculator; 048 private final int interval; 049 private final String outputFile; 050 private final MatsimServices matsimServices; 051 052 private Function<Object[], String[]> valuesToStringsConverter = TimeProfiles::combineValuesIntoStrings; 053 private CompactCSVWriter writer; 054 055 public XYDataCollector(Iterable<T> monitoredObjects, XYDataCalculator<T> calculator, int interval, 056 String outputFile, MatsimServices matsimServices) { 057 this.monitoredObjects = monitoredObjects; 058 this.calculator = calculator; 059 this.interval = interval; 060 this.outputFile = outputFile; 061 this.matsimServices = matsimServices; 062 } 063 064 @Override 065 public void notifyMobsimInitialized(@SuppressWarnings("rawtypes") MobsimInitializedEvent e) { 066 String file = matsimServices.getControlerIO().getIterationFilename(matsimServices.getIterationNumber(), 067 outputFile); 068 writer = new CompactCSVWriter(IOUtils.getBufferedWriter(file + ".xy.gz")); 069 writer.writeNext("time", "id", "x", "y", calculator.getHeader()); 070 } 071 072 @Override 073 public void notifyMobsimBeforeSimStep(@SuppressWarnings("rawtypes") MobsimBeforeSimStepEvent e) { 074 if (e.getSimulationTime() % interval == 0) { 075 String time = (int)e.getSimulationTime() + ""; 076 for (T o : monitoredObjects) { 077 Coord coord = calculator.getCoord(o); 078 writer.writeNext(time, o.getId() + "", coord.getX() + "", coord.getY() + "", 079 valuesToStringsConverter.apply(calculator.calculate(o))); 080 } 081 } 082 } 083 084 public void setValuesToStringsConverter(Function<Object[], String[]> valuesToStringsConverter) { 085 this.valuesToStringsConverter = valuesToStringsConverter; 086 } 087 088 @Override 089 public void notifyMobsimBeforeCleanup(@SuppressWarnings("rawtypes") MobsimBeforeCleanupEvent e) { 090 writer.close(); 091 } 092}