diff --git a/input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz b/input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz new file mode 100644 index 0000000..12097b4 Binary files /dev/null and b/input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz differ diff --git a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java index f59cbdf..ff524e9 100644 --- a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java +++ b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java @@ -3,6 +3,7 @@ import com.google.common.collect.Lists; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; import org.locationtech.jts.geom.Geometry; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Link; @@ -10,6 +11,7 @@ import org.matsim.api.core.v01.population.*; import org.matsim.application.MATSimAppCommand; import org.matsim.application.options.ShpOptions; +import org.matsim.application.prepare.population.CleanPopulation; import org.matsim.core.config.groups.NetworkConfigGroup; import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.filter.NetworkFilterManager; @@ -34,7 +36,7 @@ public class PrepareDrtScenarioAgents implements MATSimAppCommand { @CommandLine.Parameters(arity = "1", paramLabel = "INPUT", description = "Path to input population") private Path input; @CommandLine.Option(names = "--network", description = "Path to network", required = true) - private Path networkPath; + private String networkPath; @CommandLine.Option(names = "--output", description = "Path to output population", required = true) private Path output; @CommandLine.Mixin @@ -60,7 +62,7 @@ public Integer call() throws Exception { } Population population = PopulationUtils.readPopulation(input.toString()); - Network network = NetworkUtils.readNetwork(networkPath.toString()); + Network network = NetworkUtils.readNetwork(networkPath); // convertPtToDrtTrips(population, network, shp); @@ -82,18 +84,17 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net Network filtered = manager.applyFilters(); for (Person person : population.getPersons().values()) { -// TODO: replace with static call of CleanPopulation method + CleanPopulation.removeUnselectedPlans(person); Plan selected = person.getSelectedPlan(); - for (Plan plan : Lists.newArrayList(person.getPlans())) { - if (plan != selected) - person.removePlan(plan); - } // get indexes of pt legs with new pt line - List indexes = TripStructureUtils.getLegs(selected).stream() - .filter(l -> l.getRoute().getStartLinkId().toString().contains("pt_vsp_") - && l.getRoute().getEndLinkId().toString().contains("pt_vsp_")) - .map(l -> selected.getPlanElements().indexOf(l)).toList(); + List indexes = getNewPtLineIndexes(selected); + +// only remove routes from legs if no legs with new vsp pt line + if (indexes.isEmpty()) { + TripStructureUtils.getLegs(selected).forEach(CleanPopulation::removeRouteFromLeg); + continue; + } for (Integer index : indexes) { for (int i = 0; i < selected.getPlanElements().size(); i++) { @@ -105,8 +106,10 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net person.getId(), TransportMode.walk, TransportMode.pt, i, leg.getMode(), leg.getRoutingMode()); throw new IllegalStateException(); } - leg.setRoute(null); + CleanPopulation.removeRouteFromLeg(leg); leg.setRoutingMode(TransportMode.drt); + leg.setTravelTimeUndefined(); + leg.setDepartureTimeUndefined(); continue; } @@ -130,17 +133,20 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net // pt leg with new pt line leg.setRoute(null); leg.setMode(TransportMode.drt); + leg.setTravelTimeUndefined(); + leg.setDepartureTimeUndefined(); + leg.getAttributes().removeAttribute("enterVehicleTime"); continue; } if (i == index + 1 && selected.getPlanElements().get(i) instanceof Activity act) { -// interaction act before leg +// interaction act after leg if (!act.getType().equals(PT_INTERACTION)) { logNotPtInteractionAct(person, act, i); throw new IllegalStateException(); } - if (selected.getPlanElements().get(i + 2) instanceof Activity prev) { - convertToDrtInteraction(act, prev, network, filtered); + if (selected.getPlanElements().get(i + 2) instanceof Activity next) { + convertToDrtInteraction(act, next, network, filtered); } else { logWrongPlanElementType(person, i); throw new IllegalStateException(); @@ -151,6 +157,13 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net } } + public static @NotNull List getNewPtLineIndexes(Plan selected) { + return TripStructureUtils.getLegs(selected).stream() + .filter(l -> l.getRoute().getStartLinkId().toString().contains("pt_vsp_") + && l.getRoute().getEndLinkId().toString().contains("pt_vsp_")) + .map(l -> selected.getPlanElements().indexOf(l)).toList(); + } + private static void logNotPtInteractionAct(Person person, Activity act, int i) { log.fatal("For selected plan of person {} type {} expected for activity at index {}. Activity has type {} instead. Abort.", person.getId(), PT_INTERACTION, i, act.getType()); diff --git a/src/main/java/org/matsim/run/scenarios/LausitzScenario.java b/src/main/java/org/matsim/run/scenarios/LausitzScenario.java index d082bb2..30803be 100644 --- a/src/main/java/org/matsim/run/scenarios/LausitzScenario.java +++ b/src/main/java/org/matsim/run/scenarios/LausitzScenario.java @@ -34,6 +34,7 @@ import org.matsim.run.analysis.CommunityFilter; import org.matsim.run.analysis.CommuterAnalysis; import org.matsim.run.analysis.DistanceMatrix; +import org.matsim.run.prepare.PrepareDrtScenarioAgents; import org.matsim.run.prepare.PrepareNetwork; import org.matsim.run.prepare.PreparePopulation; import org.matsim.simwrapper.SimWrapperConfigGroup; @@ -54,7 +55,8 @@ CreateNetworkFromSumo.class, CreateTransitScheduleFromGtfs.class, TrajectoryToPlans.class, GenerateShortDistanceTrips.class, MergePopulations.class, ExtractRelevantFreightTrips.class, DownSamplePopulation.class, ExtractHomeCoordinates.class, CleanNetwork.class, CreateLandUseShp.class, ResolveGridCoordinates.class, FixSubtourModes.class, AdjustActivityToLinkDistances.class, XYToLinks.class, - SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class, CleanPopulation.class, PrepareNetwork.class + SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class, CleanPopulation.class, PrepareNetwork.class, + PrepareDrtScenarioAgents.class }) @MATSimApplication.Analysis({ LinkStats.class, CheckPopulation.class, CommuterAnalysis.class, CommunityFilter.class, DistanceMatrix.class diff --git a/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java new file mode 100644 index 0000000..61b690a --- /dev/null +++ b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java @@ -0,0 +1,75 @@ +package org.matsim.run.prepare; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.population.*; +import org.matsim.application.MATSimApplication; +import org.matsim.core.population.PopulationUtils; +import org.matsim.run.scenarios.LausitzScenario; +import org.matsim.testcases.MatsimTestUtils; + +import java.util.List; + +class PrepareDrtScenarioAgentsTest { + @RegisterExtension + private final MatsimTestUtils utils = new MatsimTestUtils(); + private static final String URL = String.format("https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v%s/", + LausitzScenario.VERSION); + private static final Id PERSON_ID = Id.createPersonId("642052"); + + @Test + void testPrepareDrtScenarioAgents() { + String inputPopulationPath = "./input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz"; + Population in = PopulationUtils.readPopulation(inputPopulationPath); + String networkPath = URL + String.format("lausitz-v%s-network-with-pt.xml.gz", LausitzScenario.VERSION); + String outPath = utils.getOutputDirectory() + "/drt-test-population.xml.gz"; + + assert MATSimApplication.execute(LausitzScenario.class, "prepare", "prepare-drt-agents", + inputPopulationPath, + "--network", networkPath, + "--output", outPath, + "--shp", "./input/shp/lausitz.shp") + == 0 : "Must return non error code"; + + Population out = PopulationUtils.readPopulation(outPath); + List outSelectedPlanElements = out.getPersons().get(PERSON_ID).getSelectedPlan().getPlanElements(); + +// there is only 1 person in the population + for (int index : PrepareDrtScenarioAgents.getNewPtLineIndexes(in.getPersons().get(PERSON_ID).getSelectedPlan())) { +// access leg + Assertions.assertInstanceOf(Leg.class, outSelectedPlanElements.get(index - 2)); + Leg access = (Leg) outSelectedPlanElements.get(index - 2); + Assertions.assertNull(access.getRoute()); + Assertions.assertEquals(TransportMode.drt, access.getRoutingMode()); + +// interaction act before leg + Assertions.assertInstanceOf(Activity.class, outSelectedPlanElements.get(index - 1)); + Activity before = (Activity) outSelectedPlanElements.get(index - 1); + Assertions.assertNull(before.getCoord()); + Assertions.assertNull(before.getFacilityId()); + Assertions.assertEquals("drt interaction", before.getType()); + +// pt leg which was converted to drt leg + Assertions.assertInstanceOf(Leg.class, outSelectedPlanElements.get(index)); + Leg leg = (Leg) outSelectedPlanElements.get(index); + Assertions.assertNull(leg.getRoute()); + Assertions.assertEquals(TransportMode.drt, leg.getMode()); + + // interaction act after leg + Assertions.assertInstanceOf(Activity.class, outSelectedPlanElements.get(index + 1)); + Activity after = (Activity) outSelectedPlanElements.get(index + 1); + Assertions.assertNull(after.getCoord()); + Assertions.assertNull(after.getFacilityId()); + Assertions.assertEquals("drt interaction", after.getType()); + + // egress leg + Assertions.assertInstanceOf(Leg.class, outSelectedPlanElements.get(index + 2)); + Leg egress = (Leg) outSelectedPlanElements.get(index + 2); + Assertions.assertNull(egress.getRoute()); + Assertions.assertEquals(TransportMode.drt, egress.getRoutingMode()); + } + } +}