Skip to content

Commit

Permalink
feat: some updates from internal repositories
Browse files Browse the repository at this point in the history
  • Loading branch information
sebhoerl committed Mar 7, 2024
1 parent 09c830f commit 3d4169c
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.eqasim.core.analysis.legs.LegListener;
import org.eqasim.core.analysis.pt.PublicTransportLegListener;
import org.eqasim.core.analysis.trips.TripListener;
import org.eqasim.core.simulation.analysis.stuck.StuckAnalysisModule;
import org.eqasim.core.simulation.modes.drt.analysis.DrtAnalysisModule;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
Expand All @@ -20,6 +21,7 @@ public class EqasimAnalysisModule extends AbstractModule {
@Override
public void install() {
addControlerListenerBinding().to(AnalysisOutputListener.class);

if(getConfig().getModules().containsKey(MultiModeDrtConfigGroup.GROUP_NAME)) {
install(new DrtAnalysisModule());
} else {
Expand All @@ -28,6 +30,8 @@ public void install() {
bind(DefaultPersonAnalysisFilter.class);
bind(PersonAnalysisFilter.class).to(DefaultPersonAnalysisFilter.class);
}

install(new StuckAnalysisModule());
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.eqasim.core.simulation.analysis.stuck;

import org.matsim.api.core.v01.events.PersonStuckEvent;
import org.matsim.api.core.v01.events.handler.PersonStuckEventHandler;

public class StuckAnalysisHandler implements PersonStuckEventHandler {
private int count = 0;

@Override
public void handleEvent(PersonStuckEvent event) {
count += 1;
}

@Override
public void reset(int iteration) {
this.count = 0;
}

public int getCount() {
return count;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.eqasim.core.simulation.analysis.stuck;

import java.io.BufferedWriter;
import java.io.IOException;

import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.events.IterationStartsEvent;
import org.matsim.core.controler.events.StartupEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
import org.matsim.core.controler.listener.IterationStartsListener;
import org.matsim.core.controler.listener.StartupListener;
import org.matsim.core.utils.io.IOUtils;

import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class StuckAnalysisListener implements StartupListener, IterationStartsListener, IterationEndsListener {
static public final String OUTPUT_NAME = "stuck_analysis.csv";

private final EventsManager eventsManager;
private final OutputDirectoryHierarchy outputHierarchy;

private final StuckAnalysisHandler handler = new StuckAnalysisHandler();

@Inject
public StuckAnalysisListener(EventsManager eventsManager, OutputDirectoryHierarchy outputHierarchy) {
this.outputHierarchy = outputHierarchy;
this.eventsManager = eventsManager;
}

@Override
public void notifyIterationStarts(IterationStartsEvent event) {
eventsManager.addHandler(handler);
}

@Override
public void notifyStartup(StartupEvent event) {
try {
BufferedWriter writer = IOUtils.getBufferedWriter(
IOUtils.getFileUrl(outputHierarchy.getOutputFilename(OUTPUT_NAME)), IOUtils.CHARSET_UTF8, false);
writer.write(String.join(";", new String[] { "iteration", "count" }) + "\n");
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public void notifyIterationEnds(IterationEndsEvent event) {
eventsManager.removeHandler(handler);

try {
BufferedWriter writer = IOUtils.getBufferedWriter(
IOUtils.getFileUrl(outputHierarchy.getOutputFilename(OUTPUT_NAME)), IOUtils.CHARSET_UTF8, true);
writer.write(String.join(";",
new String[] { String.valueOf(event.getIteration()), String.valueOf(handler.getCount()) }) + "\n");
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.eqasim.core.simulation.analysis.stuck;

import org.matsim.core.controler.AbstractModule;

public class StuckAnalysisModule extends AbstractModule {
@Override
public void install() {
addControlerListenerBinding().to(StuckAnalysisListener.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package org.eqasim.core.tools;

import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;

import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geopkg.FeatureEntry;
import org.geotools.geopkg.GeoPackage;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.config.CommandLine;
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.network.io.MatsimNetworkReader;
import org.matsim.core.utils.geometry.geotools.MGC;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

public class ExportNetworkToGeopackage {
public static void main(String[] args) throws Exception {
CommandLine cmd = new CommandLine.Builder(args) //
.requireOptions("network-path", "output-path", "crs") //
.allowOptions("modes") //
.build();

String networkPath = cmd.getOptionStrict("network-path");

Network network = NetworkUtils.createNetwork();
new MatsimNetworkReader(network).readFile(networkPath);

CoordinateReferenceSystem crs = MGC.getCRS(cmd.getOptionStrict("crs"));
Collection<String> modes = new HashSet<>();

Arrays.asList(cmd.getOption("modes").orElse("car").split(",")).forEach(mode -> {
modes.add(mode.trim());
});

SimpleFeatureTypeBuilder featureTypeBuilder = new SimpleFeatureTypeBuilder();

featureTypeBuilder.setName("network");
featureTypeBuilder.setCRS(crs);
featureTypeBuilder.setDefaultGeometry("geometry");

featureTypeBuilder.add("link", String.class);
featureTypeBuilder.add("from", String.class);
featureTypeBuilder.add("to", String.class);
featureTypeBuilder.add("osm", String.class);
featureTypeBuilder.add("lanes", Integer.class);
featureTypeBuilder.add("capacity", Double.class);
featureTypeBuilder.add("freespeed", Double.class);
featureTypeBuilder.add("geometry", LineString.class);

SimpleFeatureType featureType = featureTypeBuilder.buildFeatureType();

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
Collection<SimpleFeature> features = new LinkedList<>();

GeometryFactory geometryFactory = new GeometryFactory();

for (Link link : network.getLinks().values()) {
boolean isSelected = false;

for (String mode : link.getAllowedModes()) {
if (modes.contains(mode)) {
isSelected = true;
}
}

if (isSelected) {
Coordinate fromCoordinate = new Coordinate(link.getFromNode().getCoord().getX(),
link.getFromNode().getCoord().getY());
Coordinate toCoordinate = new Coordinate(link.getToNode().getCoord().getX(),
link.getToNode().getCoord().getY());

featureBuilder.add(link.getId().toString());
featureBuilder.add(link.getFromNode().getId().toString());
featureBuilder.add(link.getToNode().getId().toString());
featureBuilder.add(link.getAttributes().getAttribute("osm:way:highway"));
featureBuilder.add(link.getNumberOfLanes());
featureBuilder.add(link.getCapacity());
featureBuilder.add(link.getFreespeed());

featureBuilder.add(geometryFactory.createLineString(new Coordinate[] { fromCoordinate, toCoordinate }));
features.add(featureBuilder.buildFeature(null));
}
}

// Wrap up
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
featureCollection.addAll(features);

// Write
File outputPath = new File(cmd.getOptionStrict("output-path"));

if (outputPath.exists()) {
outputPath.delete();
}

GeoPackage outputPackage = new GeoPackage(outputPath);
outputPackage.init();

FeatureEntry featureEntry = new FeatureEntry();
outputPackage.add(featureEntry, featureCollection);

outputPackage.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static void main(String[] args) throws Exception {
.addAttribute("line_name", String.class)//
.addAttribute("route_id", String.class) //
.addAttribute("mode", String.class) //
.addAttribute("description", String.class) //
.create();

Network network = scenario.getNetwork();
Expand Down Expand Up @@ -108,7 +109,8 @@ public static void main(String[] args) throws Exception {
transitLine.getId().toString(),
transitLine.getName(),//
transitRoute.getId().toString(), //
transitRoute.getTransportMode(),//
transitRoute.getTransportMode(), //
transitRoute.getDescription() //
}, null);

features.add(feature);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public static void main(String[] args) throws Exception {
.setCrs(crs).setName("id") //
.addAttribute("id", String.class) //
.addAttribute("link", String.class) //
.addAttribute("name", String.class) //
.create();

for (TransitStopFacility stopFacility : scenario.getTransitSchedule().getFacilities().values()) {
Expand All @@ -46,7 +47,8 @@ public static void main(String[] args) throws Exception {
coordinate, //
new Object[] { //
stopFacility.getId().toString(), //
stopFacility.getLinkId().toString() //
stopFacility.getLinkId().toString(), //
stopFacility.getName() //
}, null);

features.add(feature);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class RunImputeHeadway {
static public void main(String[] args) throws ConfigurationException, InterruptedException {
CommandLine cmd = new CommandLine.Builder(args) //
.requireOptions("config-path", "output-path") //
.allowOptions("threads", "batch-size") //
.allowOptions("threads", "batch-size", "interval") //
.build();

EqasimConfigurator configurator = new EqasimConfigurator();
Expand All @@ -29,13 +29,14 @@ static public void main(String[] args) throws ConfigurationException, Interrupte
int batchSize = cmd.getOption("batch-size").map(Integer::parseInt).orElse(100);
int numberOfThreads = cmd.getOption("threads").map(Integer::parseInt)
.orElse(Runtime.getRuntime().availableProcessors());

double interval = cmd.getOption("interval").map(Double::parseDouble).orElse(3600.0);

Scenario scenario = ScenarioUtils.createScenario(config);
ScenarioUtils.loadScenario(scenario);

Injector injector = new InjectorBuilder(scenario) //
.addOverridingModules(configurator.getModules()) //
.addOverridingModule(new HeadwayImputerModule(numberOfThreads, batchSize, true, 2.0 * 3600.0)) //
.addOverridingModule(new HeadwayImputerModule(numberOfThreads, batchSize, true, interval)) //
.build();

HeadwayImputer headwayImputer = injector.getInstance(HeadwayImputer.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.eqasim.core.tools.schedule;

import java.util.LinkedList;
import java.util.List;

import org.matsim.api.core.v01.Id;
import org.matsim.pt.transitSchedule.api.Departure;
import org.matsim.pt.transitSchedule.api.TransitLine;
import org.matsim.pt.transitSchedule.api.TransitRoute;
import org.matsim.pt.transitSchedule.api.TransitSchedule;
import org.matsim.pt.transitSchedule.api.TransitScheduleFactory;

public class ExtendSchedule {
private final static String DEPATURE_PREFIX = "extension:";
private final static double OFFSET = 24.0 * 3600.0;

private final double time;

public ExtendSchedule(double time) {
this.time = time;
}

public void process(TransitSchedule schedule) {
TransitScheduleFactory factory = schedule.getFactory();

for (TransitLine transitLine : schedule.getTransitLines().values()) {
for (TransitRoute transitRoute : transitLine.getRoutes().values()) {
List<Departure> extensions = new LinkedList<>();

for (Departure departure : transitRoute.getDepartures().values()) {
if (departure.getDepartureTime() <= time) {
Departure extension = factory.createDeparture( //
Id.create(DEPATURE_PREFIX + departure.getId().toString(), Departure.class), //
departure.getDepartureTime() + OFFSET);

extension.setVehicleId(departure.getVehicleId());
extensions.add(extension);
}
}

for (Departure extension : extensions) {
transitRoute.addDeparture(extension);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.eqasim.core.tools.schedule;

import org.matsim.api.core.v01.Scenario;
import org.matsim.core.config.CommandLine;
import org.matsim.core.config.CommandLine.ConfigurationException;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.scenario.ScenarioUtils;
import org.matsim.pt.transitSchedule.api.TransitScheduleReader;
import org.matsim.pt.transitSchedule.api.TransitScheduleWriter;

public class RunExtendSchedule {
static public void main(String[] args) throws ConfigurationException {
CommandLine cmd = new CommandLine.Builder(args) //
.requireOptions("schedule-path", "output-path", "period") //
.build();

Config config = ConfigUtils.createConfig();
Scenario scenario = ScenarioUtils.createScenario(config);
new TransitScheduleReader(scenario).readFile(cmd.getOptionStrict("schedule-path"));
new ExtendSchedule(Double.parseDouble(cmd.getOptionStrict("period"))).process(scenario.getTransitSchedule());
new TransitScheduleWriter(scenario.getTransitSchedule()).writeFile(cmd.getOptionStrict("output-path"));
}
}
Loading

0 comments on commit 3d4169c

Please sign in to comment.