Skip to content

Commit

Permalink
Merge branch 'develop' into feat/vdf-sparse-horizon
Browse files Browse the repository at this point in the history
  • Loading branch information
tkchouaki authored Nov 26, 2024
2 parents 05f84a8 + 678fbb0 commit 84e5c08
Show file tree
Hide file tree
Showing 46 changed files with 1,186 additions and 58 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ included in the (note yet determined) next version number.

**Development version**

- Improve Emissions tools in order to handle unknown Osm highway tag values when mapping HBEFA road types
- add configurable policies for IDF
- Introduce `travelTimeRecordingInterval` config option that decouples travel time writing from general analysis
- Add eqasim_activities.csv for analysis
- The cutters now take a GeoPackage file as an alterative to a ShapeFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.population.Person;
import org.matsim.pt.transitSchedule.api.TransitLine;
import org.matsim.pt.transitSchedule.api.TransitRoute;
import org.matsim.pt.transitSchedule.api.TransitStopArea;
import org.matsim.pt.transitSchedule.api.TransitStopFacility;
import org.matsim.pt.transitSchedule.api.*;

public class PublicTransportLegItem {
public Id<Person> personId;
Expand All @@ -20,12 +17,13 @@ public class PublicTransportLegItem {

public Id<TransitStopArea> accessAreaId;
public Id<TransitStopArea> egressAreaId;
public Id<Departure> departureId;

public String transitMode;

public PublicTransportLegItem(Id<Person> personId, int personTripId, int legIndex,
Id<TransitStopFacility> accessStopId, Id<TransitStopFacility> egressStopId, Id<TransitLine> transitLineId,
Id<TransitRoute> transitRouteId, Id<TransitStopArea> accessAreaId, Id<TransitStopArea> egressAreaId,
Id<TransitRoute> transitRouteId, Id<TransitStopArea> accessAreaId, Id<TransitStopArea> egressAreaId, Id<Departure> departureId,
String transitMode) {
this.personId = personId;
this.personTripId = personTripId;
Expand All @@ -39,6 +37,7 @@ public PublicTransportLegItem(Id<Person> personId, int personTripId, int legInde

this.accessAreaId = accessAreaId;
this.egressAreaId = egressAreaId;
this.departureId = departureId;

this.transitMode = transitMode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public void handleEvent(PublicTransitEvent event) {
event.getTransitLineId(), //
event.getTransitRouteId(), //
accessAreaId, //
egressAreaId, //
egressAreaId,
event.getDepartureId(),//
routeMode //
));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public Collection<PublicTransportLegItem> getPublicTransportLegs(Person person)
Id<TransitStopArea> egressStopAreaId = this.transitSchedule.getFacilities().get(transitPassengerRoute.getEgressStopId()).getStopAreaId();
String mode = this.transitSchedule.getTransitLines().get(transitPassengerRoute.getLineId()).getRoutes().get(transitPassengerRoute.getRouteId()).getTransportMode();

PublicTransportLegItem item = new PublicTransportLegItem(person.getId(), tripIndex, legIndex, transitPassengerRoute.getAccessStopId(), transitPassengerRoute.getEgressStopId(), transitPassengerRoute.getLineId(), transitPassengerRoute.getRouteId(), accessStopAreaId, egressStopAreaId, mode);
//Cannot read a departure ID from a population, as it is determined during MOBSim. We put a null value here.
PublicTransportLegItem item = new PublicTransportLegItem(person.getId(), tripIndex, legIndex, transitPassengerRoute.getAccessStopId(), transitPassengerRoute.getEgressStopId(), transitPassengerRoute.getLineId(), transitPassengerRoute.getRouteId(), accessStopAreaId, egressStopAreaId, null, mode);
legItems.add(item);
}
return legItems;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ private String formatHeader() {
"access_stop_id", //
"egress_stop_id", //
"transit_line_id", //
"transit_route_id", //
"transit_route_id",
"departure_id",//
"access_area_id", //
"egress_area_id", //
"transit_mode" //
Expand All @@ -57,7 +58,8 @@ private String formatTrip(PublicTransportLegItem trip) {
trip.accessStopId.toString(), //
trip.egressStopId.toString(), //
trip.transitLineId.toString(), //
trip.transitRouteId.toString(), //
trip.transitRouteId.toString(),
trip.departureId == null ? "" : trip.departureId.toString(), //
trip.accessAreaId == null ? "" : trip.accessAreaId.toString(), //
trip.egressAreaId == null ? "" : trip.egressAreaId.toString(), //
trip.transitMode //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.emissions.EmissionModule;
import org.matsim.contrib.emissions.OsmHbefaMapping;
import org.matsim.contrib.emissions.utils.EmissionsConfigGroup;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.config.CommandLine;
Expand Down Expand Up @@ -60,7 +59,10 @@ public static void main(String[] args) throws CommandLine.ConfigurationException
Scenario scenario = ScenarioUtils.createScenario(config);
ScenarioUtils.loadScenario(scenario);

OsmHbefaMapping osmHbefaMapping = OsmHbefaMapping.build();
// the default hbefa type is URB/Acess/30 but can be changed like this
// SafeOsmHbefaMapping.defaultType = "URB/Local/50";
SafeOsmHbefaMapping osmHbefaMapping = new SafeOsmHbefaMapping();

Network network = scenario.getNetwork();
// if the network is from pt2matsim it might not have "type" but "osm:way:highway" attribute instead
for (Link link: network.getLinks().values()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.eqasim.core.components.emissions;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.emissions.HbefaRoadTypeMapping;
import org.matsim.contrib.emissions.OsmHbefaMapping;
import org.matsim.core.network.NetworkUtils;

// This class is designed to wrap the matsim-libs emissions contrib OsmHbefaMapping by providing a default hbefa type for unknown osm keys (instead of throwing a RuntimeException
public class SafeOsmHbefaMapping extends HbefaRoadTypeMapping {

private final static OsmHbefaMapping osmHbefaMapping = OsmHbefaMapping.build();
private final static Logger log = LogManager.getLogger(SafeOsmHbefaMapping.class);
public static String defaultType = "URB/Access/30";

@Override
public String determineHbefaType(Link link) {
String result;
try {
result = osmHbefaMapping.determineHbefaType(link);
} catch (RuntimeException runtimeException) {
String type = (String) link.getAttributes().getAttribute(NetworkUtils.TYPE);
log.warn("'" + type + "' not in hbefa map; setting to " + defaultType);
result = defaultType;
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public boolean handleDeparture(double now, MobsimAgent agent, Id<Link> departure
Id<Link> arrivalLinkId = transitSchedule.getFacilities().get(route.getEgressStopId()).getLinkId();

PublicTransitEvent transitEvent = new PublicTransitEvent(arrivalTime, agent.getId(),
transitLine.getId(), transitRoute.getId(), route.getAccessStopId(), route.getEgressStopId(),
transitLine.getId(), transitRoute.getId(), route.getAccessStopId(), route.getEgressStopId(), stopDeparture.departure.getId(),
vehicleDepartureTime, route.getDistance());

internalInterface.registerAdditionalAgentOnLink(agent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.events.HasPersonId;
import org.matsim.api.core.v01.population.Person;
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.TransitStopFacility;
Expand All @@ -18,11 +19,12 @@ public class PublicTransitEvent extends GenericEvent implements HasPersonId {
final private Id<TransitRoute> transitRouteId;
final private Id<TransitStopFacility> accessStopId;
final private Id<TransitStopFacility> egressStopId;
final private Id<Departure> departureId;
final private double vehicleDepartureTime;
final private double travelDistance;

public PublicTransitEvent(double arrivalTime, Id<Person> personId, Id<TransitLine> transitLineId,
Id<TransitRoute> transitRouteId, Id<TransitStopFacility> accessStopId, Id<TransitStopFacility> egressStopId,
Id<TransitRoute> transitRouteId, Id<TransitStopFacility> accessStopId, Id<TransitStopFacility> egressStopId, Id<Departure> departureId,
double vehicleDepartureTime, double travelDistance) {
super(TYPE, arrivalTime);

Expand All @@ -31,13 +33,14 @@ public PublicTransitEvent(double arrivalTime, Id<Person> personId, Id<TransitLin
this.transitRouteId = transitRouteId;
this.accessStopId = accessStopId;
this.egressStopId = egressStopId;
this.departureId = departureId;
this.vehicleDepartureTime = vehicleDepartureTime;
this.travelDistance = travelDistance;
}

public PublicTransitEvent(double now, PublicTransitEvent delegate) {
this(now, delegate.getPersonId(), delegate.getTransitLineId(), delegate.getTransitRouteId(),
delegate.getAccessStopId(), delegate.getEgressStopId(), delegate.getVehicleDepartureTime(),
delegate.getAccessStopId(), delegate.getEgressStopId(), delegate.getDepartureId(), delegate.getVehicleDepartureTime(),
delegate.getTravelDistance());
}

Expand All @@ -57,6 +60,10 @@ public Id<TransitStopFacility> getEgressStopId() {
return egressStopId;
}

public Id<Departure> getDepartureId() {
return departureId;
}

public double getVehicleDepartureTime() {
return vehicleDepartureTime;
}
Expand All @@ -83,6 +90,7 @@ public Map<String, String> getAttributes() {
attributes.put("route", transitRouteId.toString());
attributes.put("accessStop", accessStopId.toString());
attributes.put("egressStop", egressStopId.toString());
attributes.put("departure", departureId.toString());
attributes.put("vehicleDepartureTime", String.valueOf(vehicleDepartureTime));
attributes.put("travelDistance", String.valueOf(travelDistance));
return attributes;
Expand All @@ -98,9 +106,10 @@ public static PublicTransitEvent convert(GenericEvent genericEvent) {
Id<TransitRoute> transitRouteId = Id.create(attributes.get("route"), TransitRoute.class);
Id<TransitStopFacility> accessStopId = Id.create(attributes.get("accessStop"), TransitStopFacility.class);
Id<TransitStopFacility> egressStopId = Id.create(attributes.get("egressStop"), TransitStopFacility.class);
Id<Departure> departureId = Id.create(attributes.get("departure"), Departure.class);
double vehicleDepartureTime = Double.parseDouble(attributes.get("vehicleDepartureTime"));
double travelDistance = Double.parseDouble(attributes.get("travelDistance"));

return new PublicTransitEvent(genericEvent.getTime(), personId, transitLineId, transitRouteId, accessStopId, egressStopId, vehicleDepartureTime, travelDistance);
return new PublicTransitEvent(genericEvent.getTime(), personId, transitLineId, transitRouteId, accessStopId, egressStopId, departureId, vehicleDepartureTime, travelDistance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.population.Person;
import org.matsim.core.events.MatsimEventsReader.CustomEventMapper;
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.TransitStopFacility;
Expand All @@ -19,10 +20,11 @@ public PublicTransitEvent apply(GenericEvent event) {
TransitStopFacility.class);
Id<TransitStopFacility> egressStopId = Id.create(event.getAttributes().get("egressStop"),
TransitStopFacility.class);
Id<Departure> departureId = Id.create(event.getAttributes().get("departure"), Departure.class);
double vehicleDepartureTime = Double.parseDouble(event.getAttributes().get("vehicleDepartureTime"));
double travelDistance = Double.parseDouble(event.getAttributes().get("travelDistance"));

return new PublicTransitEvent(arrivalTime, personId, transitLineId, transitRouteId, accessStopId, egressStopId,
return new PublicTransitEvent(arrivalTime, personId, transitLineId, transitRouteId, accessStopId, egressStopId, departureId,
vehicleDepartureTime, travelDistance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ static public void insertVehicles(Config config, Scenario scenario) {
VehiclesFactory factory = vehicles.getFactory();

VehicleType vehicleType = VehicleUtils.createVehicleType(Id.create("defaultVehicleType", VehicleType.class));
vehicleType.setNetworkMode("car");
vehicles.addVehicleType(vehicleType);
for (Person person : scenario.getPopulation().getPersons().values()) {
Map<String, Id<Vehicle>> personVehicles = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package org.eqasim.core.tools;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.lang3.BooleanUtils;
import org.geotools.api.referencing.crs.CoordinateReferenceSystem;
import org.locationtech.jts.geom.Coordinate;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.IdSet;
import org.matsim.api.core.v01.Scenario;
Expand All @@ -20,9 +22,7 @@
import org.matsim.core.utils.geometry.geotools.MGC;
import org.matsim.core.utils.gis.PolylineFeatureFactory;
import org.matsim.core.utils.gis.ShapeFileWriter;
import org.matsim.pt.transitSchedule.api.TransitLine;
import org.matsim.pt.transitSchedule.api.TransitRoute;
import org.matsim.pt.transitSchedule.api.TransitScheduleReader;
import org.matsim.pt.transitSchedule.api.*;
import org.geotools.api.feature.simple.SimpleFeature;

public class ExportTransitLinesToShapefile {
Expand Down Expand Up @@ -84,25 +84,34 @@ public static void main(String[] args) throws Exception {
continue;
}
NetworkRoute networkRoute = transitRoute.getRoute();
List<Link> links = new ArrayList<>(networkRoute.getLinkIds().size() + 2);
links.add(network.getLinks().get(networkRoute.getStartLinkId()));
networkRoute.getLinkIds().forEach(id -> links.add(network.getLinks().get(id)));
links.add(network.getLinks().get(networkRoute.getEndLinkId()));

Coordinate[] coordinates = new Coordinate[links.size() + 1];

for (int i = 0; i < links.size(); i++) {
Link link = links.get(i);

if (i == 0) {
coordinates[i] = new Coordinate(link.getFromNode().getCoord().getX(),
link.getFromNode().getCoord().getY());
Coordinate[] coordinates;
if(networkRoute == null) {
Function<Coord, Coordinate> coordToCoordinate = coord -> new Coordinate(coord.getX(), coord.getY());
coordinates = transitRoute.getStops().stream()
.map(TransitRouteStop::getStopFacility)
.map(TransitStopFacility::getCoord)
.map(coordToCoordinate)
.toArray(Coordinate[]::new);
} else {
List<Link> links = new ArrayList<>(networkRoute.getLinkIds().size() + 2);
links.add(network.getLinks().get(networkRoute.getStartLinkId()));
networkRoute.getLinkIds().forEach(id -> links.add(network.getLinks().get(id)));
links.add(network.getLinks().get(networkRoute.getEndLinkId()));

coordinates = new Coordinate[links.size() + 1];

for (int i = 0; i < links.size(); i++) {
Link link = links.get(i);

if (i == 0) {
coordinates[i] = new Coordinate(link.getFromNode().getCoord().getX(),
link.getFromNode().getCoord().getY());
}

coordinates[i + 1] = new Coordinate(link.getToNode().getCoord().getX(),
link.getToNode().getCoord().getY());
}

coordinates[i + 1] = new Coordinate(link.getToNode().getCoord().getX(),
link.getToNode().getCoord().getY());
}

SimpleFeature feature = linkFactory.createPolyline( //
coordinates, //
new Object[] { //
Expand All @@ -112,7 +121,6 @@ public static void main(String[] args) throws Exception {
transitRoute.getTransportMode(), //
transitRoute.getDescription() //
}, null);

features.add(feature);
}
}
Expand Down
Binary file modified core/src/main/resources/melun/network.xml.gz
Binary file not shown.
17 changes: 12 additions & 5 deletions core/src/test/java/org/eqasim/TestEmissions.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.zip.GZIPInputStream;

import org.apache.commons.io.FileUtils;
import org.eqasim.core.components.emissions.RunComputeEmissionsEvents;
import org.eqasim.core.components.emissions.RunExportEmissionsNetwork;
import org.eqasim.core.components.emissions.SafeOsmHbefaMapping;
import org.eqasim.core.simulation.EqasimConfigurator;
import org.eqasim.core.simulation.analysis.EqasimAnalysisModule;
import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension;
Expand Down Expand Up @@ -143,8 +140,16 @@ private void runModifyNetwork() {
Scenario scenario = ScenarioUtils.loadScenario(config);
Network network = scenario.getNetwork();
for (Link link : network.getLinks().values()) {

// this forces the OSM Mapping code to use URB/Local/50 as it the only thing we
// have in the sample HBEFA.
// We intentionally leave the 'pedestrian' links here to test the SafeOsmHbefaMapping class
String linkType = NetworkUtils.getType(link);
if (linkType != null) {
if (!linkType.equals("pedestrian")) {
continue;
}
}
NetworkUtils.setType(link, "tertiary");
link.getAttributes().putAttribute(NetworkUtils.ALLOWED_SPEED, 50 / 3.6);
}
Expand All @@ -159,6 +164,8 @@ private void runMelunEmissions() throws CommandLine.ConfigurationException, IOEx
Assert.assertEquals(3412, (long) counts.getOrDefault("bike", 0L));
Assert.assertEquals(2108, (long) counts.get("pt"));

SafeOsmHbefaMapping.defaultType = "URB/Loca/50";

RunComputeEmissionsEvents.main(new String[] { "--config-path", "melun_test/input/config.xml",
"--hbefa-cold-avg", "sample_41_EFA_ColdStart_vehcat_2020average.csv", "--hbefa-hot-avg",
"sample_41_EFA_HOT_vehcat_2020average.csv", "--hbefa-cold-detailed",
Expand Down
Loading

0 comments on commit 84e5c08

Please sign in to comment.