Commit dba72c92 authored by Sebastian Hörl's avatar Sebastian Hörl
Browse files

One operator

parent 45c0076c
import pandas as pd
import geopandas as gpd
import numpy as np
import shapely.geometry as geo
import sys
operating_areas_path = sys.argv[1]
output_path = sys.argv[2]
service_area_attribute_name = sys.argv[3]
waiting_time_zone_attribute_name = sys.argv[4]
hexagon_radius = int(sys.argv[5])
df_operating_areas = gpd.read_file(operating_areas_path)
corners = [
np.array([np.cos(30.0 * np.pi / 180.0), np.sin(30.0 * np.pi / 180.0)]) * hexagon_radius,
np.array([np.cos(90.0 * np.pi / 180.0), np.sin(90.0 * np.pi / 180.0)]) * hexagon_radius,
np.array([np.cos(150.0 * np.pi / 180.0), np.sin(150.0 * np.pi / 180.0)]) * hexagon_radius,
np.array([np.cos(210.0 * np.pi / 180.0), np.sin(210.0 * np.pi / 180.0)]) * hexagon_radius,
np.array([np.cos(270.0 * np.pi / 180.0), np.sin(270.0 * np.pi / 180.0)]) * hexagon_radius,
np.array([np.cos(330.0 * np.pi / 180.0), np.sin(330.0 * np.pi / 180.0)]) * hexagon_radius
]
offset_x = 2.0 * hexagon_radius * np.cos(30.0 * np.pi / 180.0)
t = 2.0 * hexagon_radius * np.cos(30.0 * np.pi / 180.0) / np.sqrt(3.0)
offset_y = hexagon_radius + 0.5 * t
geometry = []
for area_name, area_geometry in zip(df_operating_areas[service_area_attribute_name], df_operating_areas["geometry"]):
min_x, min_y, max_x, max_y = area_geometry.bounds
max_i = int(np.ceil((max_x - min_x) / offset_x)) + 1
max_j = int(np.ceil((max_y - min_y) / offset_y)) + 1
index = 0
for i in range(max_i):
for j in range(max_j):
centroid = np.array([
min_x + offset_x * i + (0.5 * offset_x if j % 2 == 0 else 0.0),
min_y + offset_y * j
])
hexagon = geo.Polygon(corners + centroid)
if hexagon.intersects(area_geometry):
geometry.append((area_name, "%s_%d" % (area_name, index), hexagon))
index += 1
df = pd.DataFrame.from_records(geometry, columns = [service_area_attribute_name, waiting_time_zone_attribute_name, "geometry"])
df = gpd.GeoDataFrame(df, crs = {"init": "EPSG:2056"})
df.to_file(output_path)
package ch.ethz.matsim.projects.astra_2018_002;
import org.matsim.core.config.ReflectiveConfigGroup;
public class ASTRAConfigGroup extends ReflectiveConfigGroup {
public final static String GROUP_NAME = "astra";
private final static String TAXI_FLEET_SIZE = "taxiFleetSize";
private final static String POOLED_FLEET_SIZE = "pooledFleetSize";
private final static String SERVICE_AREA_ATTRIBUTE = "serviceAreaAttribute";
private final static String ACTIVE_SERVICE_AREA = "activeServiceArea";
private final static String SERVICE_AREA_SHAPEFILE = "serviceAreaShapefile";
private final static String WAITING_TIME_ZONE_SHAPEFILE = "waitingTimeZoneShapefile";
private final static String WAITING_TIME_ZONE_IDENTIFIER_ATTRIBUTE = "waitingTimeZoneIdentifierAttribute";
private int taxiFleetSize = 100;
private int pooledFleetSize = 0;
private String serviceAreaAttribute = "OAREA";
private String activeServiceArea = "ZH";
private String serviceAreaShapefile = "service_area.shp";
private String waitingTimeZoneIdentifierAttribute = "WZONE";
private String waitingTimeZoneShapefile = "waiting_time_areas.shp";
public ASTRAConfigGroup() {
super(GROUP_NAME);
}
@StringGetter(TAXI_FLEET_SIZE)
public int getTaxiFleetSize() {
return taxiFleetSize;
}
@StringSetter(TAXI_FLEET_SIZE)
public void setTaxiFleetSize(int taxiFleetSize) {
this.taxiFleetSize = taxiFleetSize;
}
@StringGetter(POOLED_FLEET_SIZE)
public int getPooledFleetSize() {
return pooledFleetSize;
}
@StringSetter(POOLED_FLEET_SIZE)
public void setPooledFleetSize(int pooledFleetSize) {
this.pooledFleetSize = pooledFleetSize;
}
@StringGetter(SERVICE_AREA_ATTRIBUTE)
public String getServiceAreaAttribute() {
return serviceAreaAttribute;
}
@StringSetter(SERVICE_AREA_ATTRIBUTE)
public void setServiceAreaAttribute(String serviceAreaAttribute) {
this.serviceAreaAttribute = serviceAreaAttribute;
}
@StringGetter(ACTIVE_SERVICE_AREA)
public String getActiveServiceArea() {
return activeServiceArea;
}
@StringSetter(ACTIVE_SERVICE_AREA)
public void setActiveServiceArea(String activeServiceArea) {
this.activeServiceArea = activeServiceArea;
}
@StringGetter(SERVICE_AREA_SHAPEFILE)
public String getServiceAreaShapefile() {
return serviceAreaShapefile;
}
@StringSetter(SERVICE_AREA_SHAPEFILE)
public void setServiceAreaShapefile(String serviceAreaShapefile) {
this.serviceAreaShapefile = serviceAreaShapefile;
}
@StringGetter(WAITING_TIME_ZONE_SHAPEFILE)
public String getWaitingTimeZoneShapefile() {
return waitingTimeZoneShapefile;
}
@StringSetter(WAITING_TIME_ZONE_SHAPEFILE)
public void setWaitingTimeZoneShapefile(String waitingTimeZoneShapefile) {
this.waitingTimeZoneShapefile = waitingTimeZoneShapefile;
}
@StringGetter(WAITING_TIME_ZONE_IDENTIFIER_ATTRIBUTE)
public String getWaitingTimeZoneIdentifierAttribute() {
return waitingTimeZoneIdentifierAttribute;
}
@StringSetter(WAITING_TIME_ZONE_IDENTIFIER_ATTRIBUTE)
public void setWaitingTimeZoneIdentifierAttribute(String waitingTimeZoneIdentifierAttribute) {
this.waitingTimeZoneIdentifierAttribute = waitingTimeZoneIdentifierAttribute;
}
}
package ch.ethz.matsim.projects.astra_2018_002;
import java.util.ArrayList;
import java.util.Collection;
import org.matsim.contrib.dynagent.run.DynActivityEnginePlugin;
import org.matsim.core.config.Config;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.mobsim.qsim.AbstractQSimPlugin;
import org.matsim.core.mobsim.qsim.PopulationPlugin;
import org.matsim.core.mobsim.qsim.TeleportationPlugin;
import org.matsim.core.mobsim.qsim.changeeventsengine.NetworkChangeEventsPlugin;
import org.matsim.core.mobsim.qsim.messagequeueengine.MessageQueuePlugin;
import org.matsim.core.mobsim.qsim.qnetsimengine.QNetsimEnginePlugin;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import ch.ethz.matsim.av.framework.AVQSimPlugin;
import ch.ethz.matsim.baseline_scenario.transit.simulation.BaselineTransitPlugin;
import ch.ethz.matsim.projects.astra_2018_002.av.dynamics.AVModesQSimPlugin;
public class ASTRAQSimModule extends AbstractModule {
@Override
public void install() {
}
@Provides
@Singleton
public Collection<AbstractQSimPlugin> provideAbstractQSimPlugins(Config config) {
final Collection<AbstractQSimPlugin> plugins = new ArrayList<>();
plugins.add(new MessageQueuePlugin(config));
plugins.add(new DynActivityEnginePlugin(config));
plugins.add(new QNetsimEnginePlugin(config));
if (config.network().isTimeVariantNetwork()) {
plugins.add(new NetworkChangeEventsPlugin(config));
}
if (config.transit().isUseTransit()) {
plugins.add(new BaselineTransitPlugin(config));
}
plugins.add(new TeleportationPlugin(config));
plugins.add(new PopulationPlugin(config));
plugins.add(new AVQSimPlugin(config));
plugins.add(new AVModesQSimPlugin(config));
return plugins;
}
}
package ch.ethz.matsim.projects.astra_2018_002;
import java.io.File;
import org.matsim.api.core.v01.Scenario;
import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
import org.matsim.contrib.dvrp.trafficmonitoring.DvrpTravelTimeModule;
......@@ -17,9 +15,8 @@ import ch.ethz.matsim.baseline_scenario.config.CommandLine.ConfigurationExceptio
import ch.ethz.matsim.baseline_scenario.transit.BaselineTransitModule;
import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRoute;
import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRouteFactory;
import ch.ethz.matsim.projects.astra_2018_002.av.ASTRAAVModule;
import ch.ethz.matsim.projects.astra_2018_002.av.AVConfigurator;
import ch.ethz.matsim.projects.astra_2018_002.av.operating_area.OperatingAreaModule;
import ch.ethz.matsim.projects.astra_2018_002.av.operator.OperatorModule;
import ch.ethz.matsim.projects.astra_2018_002.flow_efficiency.FlowEfficiencyConfigurator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissDiscreteModeChoiceModule;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissModeChoiceConfigurator;
......@@ -30,12 +27,21 @@ public class RunASTRA2018002 {
static public void main(String[] args) throws ConfigurationException {
CommandLine cmd = new CommandLine.Builder(args) //
.requireOptions("config-path", "model") //
.allowOptions("use-route-choice", "use-only-significant", "operator-path") //
.allowOptions("use-route-choice", "use-only-significant") //
.build();
ASTRAConfigGroup astraConfig = new ASTRAConfigGroup();
astraConfig.setActiveServiceArea("zurich");
astraConfig.setPooledFleetSize(0);
astraConfig.setTaxiFleetSize(100);
astraConfig.setServiceAreaShapefile("gis/operating_areas.shp");
astraConfig.setServiceAreaAttribute("OAREA");
astraConfig.setWaitingTimeZoneShapefile("gis/waiting_time_areas.shp");
astraConfig.setWaitingTimeZoneIdentifierAttribute("WZONE");
// Load config
Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), new DvrpConfigGroup(),
new AVConfigGroup());
new AVConfigGroup(), astraConfig);
// Adjust config
SwissModeChoiceConfigurator.configure(config);
......@@ -56,13 +62,12 @@ public class RunASTRA2018002 {
// Set up controller
Controler controler = new Controler(scenario);
controler.addOverridingModule(new DvrpTravelTimeModule());
controler.addOverridingModule(new SwissRailRaptorModule());
controler.addOverridingModule(new DvrpTravelTimeModule());
controler.addOverridingModule(new AVModule());
controler.addOverridingModule(new OperatingAreaModule());
controler.addOverridingModule(new OperatorModule(cmd.getOption("operator-path").map(File::new)));
controler.addOverridingModule(new ASTRAAVModule());
controler.addOverridingModule(new BaselineTransitModule());
// TODO: Consolidate QSim plugins
controler.addOverridingModule(new ASTRAQSimModule());
UtilitySet utilitySet = Enum.valueOf(UtilitySet.class, cmd.getOptionStrict("model"));
boolean useRouteChoice = cmd.getOption("use-route-choice").map(Boolean::parseBoolean).orElse(true);
......
package ch.ethz.matsim.projects.astra_2018_002.av;
import java.net.URL;
import java.util.List;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.population.PopulationFactory;
import org.matsim.core.config.ConfigGroup;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.router.DijkstraFactory;
import org.matsim.core.router.RoutingModule;
import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility;
import org.matsim.core.router.util.LeastCostPathCalculator;
import org.matsim.core.router.util.TravelTime;
import com.google.inject.Key;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import ch.ethz.matsim.av.config.AVConfig;
import ch.ethz.matsim.av.config.AVGeneratorConfig;
import ch.ethz.matsim.av.config.AVOperatorConfig;
import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.av.framework.AVUtils;
import ch.ethz.matsim.av.routing.AVRouteFactory;
import ch.ethz.matsim.discrete_mode_choice.modules.AbstractDiscreteModeChoiceExtension;
import ch.ethz.matsim.projects.astra_2018_002.ASTRAConfigGroup;
import ch.ethz.matsim.projects.astra_2018_002.av.analysis.WaitingTimeListener;
import ch.ethz.matsim.projects.astra_2018_002.av.routing.ASTRAAVRoutingModule;
import ch.ethz.matsim.projects.astra_2018_002.av.service_area.ServiceArea;
import ch.ethz.matsim.projects.astra_2018_002.av.service_area.ServiceAreaConstraint;
import ch.ethz.matsim.projects.astra_2018_002.av.service_area.ServiceAreaGenerator;
import ch.ethz.matsim.projects.astra_2018_002.av.service_area.ServiceAreaReader;
import ch.ethz.matsim.projects.astra_2018_002.av.waiting_time.AVWaitingTime;
import ch.ethz.matsim.projects.astra_2018_002.av.waiting_time.zonal.WaitingTimeZone;
import ch.ethz.matsim.projects.astra_2018_002.av.waiting_time.zonal.WaitingTimeZoneReader;
import ch.ethz.matsim.projects.astra_2018_002.av.waiting_time.zonal.ZonalWaitingTime;
public class ASTRAAVModule extends AbstractDiscreteModeChoiceExtension {
public static final String CONSTRAINT_NAME = "ASTRA";
public static final String GENERATOR_NAME = "ASTRA";
public static final String AV_TAXI = "av_taxi";
public static final String AV_POOL = "av_pool";
public static final String WAITING_TIME_GROUP_ATTRIBUTE = "waitingTimeGroup";
@Override
protected void installExtension() {
bindTripConstraintFactory(CONSTRAINT_NAME).to(ServiceAreaConstraint.Factory.class);
AVUtils.registerGeneratorFactory(binder(), GENERATOR_NAME, ServiceAreaGenerator.Factory.class);
addControlerListenerBinding().to(AVNetworkWriter.class);
bind(Key.get(TravelTime.class, Names.named(AV_TAXI)))
.to(Key.get(TravelTime.class, Names.named(TransportMode.car)));
bind(Key.get(TravelTime.class, Names.named(AV_POOL)))
.to(Key.get(TravelTime.class, Names.named(TransportMode.car)));
addEventHandlerBinding().to(Key.get(ZonalWaitingTime.class, Names.named(AV_TAXI)));
addEventHandlerBinding().to(Key.get(ZonalWaitingTime.class, Names.named(AV_POOL)));
addControlerListenerBinding().to(Key.get(ZonalWaitingTime.class, Names.named(AV_TAXI)));
addControlerListenerBinding().to(Key.get(ZonalWaitingTime.class, Names.named(AV_POOL)));
bind(Key.get(AVWaitingTime.class, Names.named(AV_TAXI)))
.to(Key.get(ZonalWaitingTime.class, Names.named(AV_TAXI)));
bind(Key.get(AVWaitingTime.class, Names.named(AV_POOL)))
.to(Key.get(ZonalWaitingTime.class, Names.named(AV_POOL)));
addControlerListenerBinding().to(WaitingTimeListener.class);
}
@Provides
@Named(AV_TAXI)
public RoutingModule provideAvTaxiRoutingModule(PopulationFactory populationFactory, AVRouteFactory routeFactory,
@Named(TransportMode.walk) RoutingModule walkRoutingModule, @Named(AVModule.AV_MODE) Network network,
@Named(AV_TAXI) AVWaitingTime waitingTime, @Named(AV_TAXI) TravelTime travelTime) {
LeastCostPathCalculator router = new DijkstraFactory().createPathCalculator(network,
new OnlyTimeDependentTravelDisutility(travelTime), travelTime);
return new ASTRAAVRoutingModule(AV_TAXI, populationFactory, routeFactory, walkRoutingModule, router, network,
travelTime, waitingTime);
}
@Provides
@Named(AV_POOL)
public RoutingModule provideAvPoolRoutingModule(PopulationFactory populationFactory, AVRouteFactory routeFactory,
@Named(TransportMode.walk) RoutingModule walkRoutingModule, @Named(AVModule.AV_MODE) Network network,
@Named(AV_POOL) AVWaitingTime waitingTime, @Named(AV_POOL) TravelTime travelTime) {
LeastCostPathCalculator router = new DijkstraFactory().createPathCalculator(network,
new OnlyTimeDependentTravelDisutility(travelTime), travelTime);
return new ASTRAAVRoutingModule(AV_POOL, populationFactory, routeFactory, walkRoutingModule, router, network,
travelTime, waitingTime);
}
@Provides
@Singleton
public ServiceAreaConstraint.Factory provideOperatingAreaConstraintFactory(ServiceArea registry) {
return new ServiceAreaConstraint.Factory(registry);
}
@Provides
@Singleton
public ServiceArea provideServiceArea(@Named(AVModule.AV_MODE) Network network, ASTRAConfigGroup astraConfig) {
ServiceAreaReader reader = new ServiceAreaReader(astraConfig.getServiceAreaAttribute(), network);
URL url = ConfigGroup.getInputFileURL(getConfig().getContext(), astraConfig.getServiceAreaShapefile());
return reader.read(astraConfig.getActiveServiceArea(), url);
}
@Provides
@Singleton
public AVConfig provideAVConfig(ASTRAConfigGroup astraConfig) {
AVConfig avConfig = new AVConfig();
AVOperatorConfig taxiConfig = avConfig.createOperatorConfig(ASTRAAVModule.AV_TAXI);
AVGeneratorConfig taxiGeneratorConfig = taxiConfig.createGeneratorConfig(ASTRAAVModule.GENERATOR_NAME);
taxiGeneratorConfig.setNumberOfVehicles(astraConfig.getTaxiFleetSize());
taxiConfig.createDispatcherConfig("SingleHeuristic");
taxiConfig.createPriceStructureConfig();
AVOperatorConfig poolConfig = avConfig.createOperatorConfig(ASTRAAVModule.AV_POOL);
AVGeneratorConfig poolGeneratorConfig = poolConfig.createGeneratorConfig(ASTRAAVModule.GENERATOR_NAME);
poolGeneratorConfig.setNumberOfVehicles(astraConfig.getPooledFleetSize());
poolConfig.createDispatcherConfig("MultiOD");
poolConfig.createPriceStructureConfig();
return avConfig;
}
@Provides
@Singleton
public List<WaitingTimeZone> provideWaitingTimeZones(@Named(AVModule.AV_MODE) Network network,
ASTRAConfigGroup astraConfig) {
WaitingTimeZoneReader reader = new WaitingTimeZoneReader(astraConfig.getWaitingTimeZoneIdentifierAttribute(),
astraConfig.getServiceAreaAttribute(), network);
URL url = ConfigGroup.getInputFileURL(getConfig().getContext(), astraConfig.getWaitingTimeZoneShapefile());
return reader.read(astraConfig.getActiveServiceArea(), url);
}
@Provides
@Singleton
@Named(AV_TAXI)
private ZonalWaitingTime provideAvTaxiWaitingTime(@Named(AVModule.AV_MODE) Network network,
List<WaitingTimeZone> waitingTimeZones) {
return provideAvWaitingTime(AV_TAXI, network, waitingTimeZones);
}
@Provides
@Singleton
@Named(AV_POOL)
private ZonalWaitingTime provideAvPoolWaitingTime(@Named(AVModule.AV_MODE) Network network,
List<WaitingTimeZone> waitingTimeZones) {
return provideAvWaitingTime(AV_POOL, network, waitingTimeZones);
}
private ZonalWaitingTime provideAvWaitingTime(String mode, Network network,
List<WaitingTimeZone> waitingTimeZones) {
double estimationStartTime = 8.0 * 3600.0;
double estimationEndTime = 22.0 * 3600.0;
double estimationInterval = 900.0;
int horizon = 10;
double defaultWaitingTime = 300.0;
return new ZonalWaitingTime(mode, estimationStartTime, estimationEndTime, estimationInterval, horizon,
defaultWaitingTime, network, waitingTimeZones);
}
@Provides
@Singleton
public WaitingTimeListener provideWaitingTimeListener(@Named(AV_TAXI) AVWaitingTime taxiWaitingTime,
@Named(AV_POOL) AVWaitingTime poolWaitingTime, List<WaitingTimeZone> waitingTimeZones,
OutputDirectoryHierarchy outputHierarchy) {
return new WaitingTimeListener(taxiWaitingTime, poolWaitingTime, waitingTimeZones, outputHierarchy);
}
}
package ch.ethz.matsim.projects.astra_2018_002.av;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ModeParams;
import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
import ch.ethz.matsim.projects.astra_2018_002.ASTRAConfigGroup;
public class AVConfigurator {
static public void configure(Config config) {
ASTRAConfigGroup astraConfig = (ASTRAConfigGroup) config.getModules().get(ASTRAConfigGroup.GROUP_NAME);
if (astraConfig == null) {
astraConfig = new ASTRAConfigGroup();
config.addModule(astraConfig);
}
ModeParams avParams = new ModeParams(AVModule.AV_MODE);
config.planCalcScore().addModeParams(avParams);
ModeParams poolParams = new ModeParams(ASTRAAVModule.AV_POOL);
config.planCalcScore().addModeParams(poolParams);
ModeParams taxiParams = new ModeParams(ASTRAAVModule.AV_TAXI);
config.planCalcScore().addModeParams(taxiParams);
DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules()
.get(DiscreteModeChoiceConfigGroup.GROUP_NAME);
Set<String> availableModes = new HashSet<>(dmcConfig.getCarModeAvailabilityConfig().getAvailableModes());
if (astraConfig.getTaxiFleetSize() > 0) {
availableModes.add(ASTRAAVModule.AV_TAXI);
}
if (astraConfig.getPooledFleetSize() > 0) {
availableModes.add(ASTRAAVModule.AV_POOL);
}
Collection<String> tripConstraints = new HashSet<>(dmcConfig.getTripConstraints());
tripConstraints.add(ASTRAAVModule.CONSTRAINT_NAME);
dmcConfig.setTripConstraints(tripConstraints);
dmcConfig.getCarModeAvailabilityConfig().setAvailableModes(availableModes);
}
}
package ch.ethz.matsim.projects.astra_2018_002.av;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.network.NetworkWriter;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.StartupEvent;
import org.matsim.core.controler.listener.StartupListener;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import ch.ethz.matsim.av.framework.AVModule;
public class AVNetworkWriter implements StartupListener {
private final OutputDirectoryHierarchy hierarchy;
private final Network network;
@Inject
public AVNetworkWriter(OutputDirectoryHierarchy hierarchy, @Named(AVModule.AV_MODE) Network network) {
this.hierarchy = hierarchy;
this.network = network;
}
@Override
public void notifyStartup(StartupEvent event) {
new NetworkWriter(network).write(hierarchy.getOutputFilename("av_network.xml.gz"));
}
}
package ch.ethz.matsim.projects.astra_2018_002.av.analysis;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Optional;
import org.matsim.api.core.v01.network.Link;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
import org.matsim.core.router.LinkWrapperFacility;
import org.matsim.core.utils.misc.Time;
import ch.ethz.matsim.projects.astra_2018_002.av.waiting_time.AVWaitingTime;
import ch.ethz.matsim.projects.astra_2018_002.av.waiting_time.zonal.WaitingTimeZone;
public class WaitingTimeListener implements IterationEndsListener {
private final static String FILE_NAME = "waiting_times.csv";
private final List<WaitingTimeZone> waitingTimeZones;
private final AVWaitingTime taxiWaitingTime;
private final AVWaitingTime poolWaitingTime;
private final OutputDirectoryHierarchy outputHierarchy;
public WaitingTimeListener(AVWaitingTime taxiWaitingTime, AVWaitingTime poolWaitingTime,
List<WaitingTimeZone> waitingTimeZones, OutputDirectoryHierarchy outputHierarchy) {
this.taxiWaitingTime = taxiWaitingTime;
this.poolWaitingTime = poolWaitingTime;
this.waitingTimeZones = waitingTimeZones;
this.outputHierarchy = outputHierarchy;
}