diff --git a/CHANGELOG.md b/CHANGELOG.md index eb3de397e..f3adaa375 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ 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 diff --git a/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java b/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java index a3aa06fdf..c7c9984b5 100644 --- a/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java +++ b/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java @@ -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; @@ -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()) { diff --git a/core/src/main/java/org/eqasim/core/components/emissions/SafeOsmHbefaMapping.java b/core/src/main/java/org/eqasim/core/components/emissions/SafeOsmHbefaMapping.java new file mode 100644 index 000000000..d779fbd2a --- /dev/null +++ b/core/src/main/java/org/eqasim/core/components/emissions/SafeOsmHbefaMapping.java @@ -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; + } + +} diff --git a/core/src/main/resources/melun/network.xml.gz b/core/src/main/resources/melun/network.xml.gz index f5f7a50cd..48f307365 100644 Binary files a/core/src/main/resources/melun/network.xml.gz and b/core/src/main/resources/melun/network.xml.gz differ diff --git a/core/src/test/java/org/eqasim/TestEmissions.java b/core/src/test/java/org/eqasim/TestEmissions.java index 7ce129995..9486550d9 100644 --- a/core/src/test/java/org/eqasim/TestEmissions.java +++ b/core/src/test/java/org/eqasim/TestEmissions.java @@ -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; @@ -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); } @@ -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",