Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace population comparison in tests and deprecate by byte comparison of plan files #3246

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
import org.matsim.api.core.v01.BasicLocation;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Identifiable;
import org.matsim.api.core.v01.network.Link;
import org.matsim.utils.objectattributes.attributable.Attributable;

import javax.annotation.Nullable;
import java.util.List;

public interface Zone extends BasicLocation, Identifiable<Zone> {
public interface Zone extends BasicLocation, Identifiable<Zone>, Attributable {
@Nullable
PreparedPolygon getPreparedGeometry();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import org.locationtech.jts.geom.prep.PreparedPolygon;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.core.utils.geometry.geotools.MGC;
import org.matsim.utils.objectattributes.attributable.Attributes;
import org.matsim.utils.objectattributes.attributable.AttributesImpl;

import javax.annotation.Nullable;
import java.util.List;

public class ZoneImpl implements Zone {

Expand All @@ -17,6 +17,9 @@ public class ZoneImpl implements Zone {
private final Coord centroid;
private String type;

private final Attributes attributes = new AttributesImpl();


public ZoneImpl(Id<Zone> id, PreparedPolygon preparedGeometry, @Nullable String type) {
this(id, preparedGeometry, MGC.point2Coord(preparedGeometry.getGeometry().getCentroid()), type);
}
Expand Down Expand Up @@ -67,4 +70,8 @@ public static ZoneImpl createDummyZone(Id<Zone> id, Coord centroid) {
return new ZoneImpl(id, null, centroid, null);
}

@Override
public Attributes getAttributes() {
return attributes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import one.util.streamex.StreamEx;
import org.apache.commons.lang3.tuple.Pair;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygonal;
import org.locationtech.jts.geom.prep.PreparedGeometry;
import org.locationtech.jts.geom.prep.PreparedPolygon;
import org.matsim.api.core.v01.Id;
Expand All @@ -26,6 +27,9 @@
import org.matsim.contrib.common.zones.util.ZoneFinderImpl;
import org.matsim.core.config.ConfigGroup;
import org.matsim.core.utils.geometry.geotools.MGC;
import org.matsim.core.utils.gis.GeoFileReader;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand All @@ -39,14 +43,15 @@
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;
import static org.matsim.utils.gis.shp2matsim.ShpGeometryUtils.loadPreparedPolygons;

/**
* @author nkuehnel / MOIA
*/
public final class ZoneSystemUtils {


public static final String THE_GEOM = "the_geom";

private ZoneSystemUtils() {}

public static ZoneSystem createZoneSystem(Network network, ZoneSystemParams zoneSystemParams) {
Expand All @@ -65,11 +70,9 @@ public static ZoneSystem createZoneSystem(@Nullable URL context, @Nonnull Networ
case GISFileZoneSystemParams.SET_NAME -> {
Preconditions.checkNotNull(((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile);
Preconditions.checkNotNull(context);

final List<PreparedPolygon> preparedGeometries = loadPreparedPolygons(
ConfigGroup.getInputFileURL(context, ((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile));
yield ZoneSystemUtils.createFromPreparedGeometries(network,
EntryStream.of(preparedGeometries).mapKeys(i -> (i + 1) + "").toMap());
URL url = ConfigGroup.getInputFileURL(context, ((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile);
Collection<SimpleFeature> features = GeoFileReader.getAllFeatures(url);
yield ZoneSystemUtils.createFromFeatures(network, features);
}
case SquareGridZoneSystemParams.SET_NAME -> {
Preconditions.checkNotNull(((SquareGridZoneSystemParams) zoneSystemParams).cellSize);
Expand All @@ -90,35 +93,52 @@ public static ZoneSystem createZoneSystem(@Nullable URL context, @Nonnull Networ
return zoneSystem;
}

public static ZoneSystem createFromPreparedGeometries(Network network, Map<String, PreparedPolygon> geometries) {
public static ZoneSystem createFromFeatures(Network network, Collection<SimpleFeature> features) {

Map<String, PreparedFeature> featureById = StreamEx.of(features.stream())
.mapToEntry(SimpleFeature::getID, sf -> new PreparedFeature(sf, new PreparedPolygon((Polygonal) sf.getDefaultGeometry())))
.toMap();

//geometries without links are skipped
Map<String, List<Link>> linksByGeometryId = StreamEx.of(network.getLinks().values())
.mapToEntry(l -> getGeometryIdForLink(l, geometries), l -> l)
.mapToEntry(l -> getGeometryIdForLink(l, featureById), l -> l)
.filterKeys(Objects::nonNull)
.grouping(toList());

//the zonal system contains only zones that have at least one link
Map<Id<Zone>, Zone> zones = EntryStream.of(linksByGeometryId)
.mapKeyValue((id, links) -> new ZoneImpl(Id.create(id, Zone.class), geometries.get(id), null))
.mapKeyValue((id, links) -> {
PreparedFeature preparedFeature = featureById.get(id);
ZoneImpl zone = new ZoneImpl(Id.create(id, Zone.class), preparedFeature.preparedPolygon, null);
for (Property attribute : preparedFeature.sf.getProperties()) {
String attributeName = attribute.getName().toString();
Object att = preparedFeature.sf().getAttribute(attributeName);
if(!attributeName.equals(THE_GEOM) && att != null) {
zone.getAttributes().putAttribute(attributeName, att);
}
}
return zone;
})
.collect(IdCollectors.toIdMap(Zone.class, Identifiable::getId, zone -> zone));


return new ZoneSystemImpl(zones.values(), new ZoneFinderImpl(zones), network);
}

private record PreparedFeature(SimpleFeature sf, PreparedPolygon preparedPolygon){}

/**
* @param link
* @return the the {@code PreparedGeometry} that contains the {@code linkId}.
* If a given link's {@code Coord} borders two or more cells, the allocation to a cell is random.
* Result may be null in case the given link is outside of the service area.
*/
@Nullable
private static String getGeometryIdForLink(Link link, Map<String, PreparedPolygon> geometries) {
private static String getGeometryIdForLink(Link link, Map<String, PreparedFeature> features) {
Point linkCoord = MGC.coord2Point(link.getToNode().getCoord());
return geometries.entrySet()
return features.entrySet()
.stream()
.filter(e -> e.getValue().intersects(linkCoord))
.filter(e -> e.getValue().preparedPolygon.intersects(linkCoord))
.findAny()
.map(Map.Entry::getKey)
.orElse(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,15 @@

package org.matsim.contrib.drt.analysis.zonal;

import com.google.common.base.Preconditions;
import one.util.streamex.EntryStream;
import org.locationtech.jts.geom.prep.PreparedGeometry;
import org.locationtech.jts.geom.prep.PreparedPolygon;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.common.zones.Zone;
import org.matsim.contrib.common.zones.ZoneSystem;
import org.matsim.contrib.common.zones.ZoneSystemParams;
import org.matsim.contrib.common.zones.ZoneSystemUtils;
import org.matsim.contrib.common.zones.systems.grid.GISFileZoneSystemParams;
import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams;
import org.matsim.contrib.common.zones.systems.grid.h3.H3ZoneSystem;
import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem;
import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams;
import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule;
import org.matsim.core.config.ConfigGroup;
import org.matsim.core.controler.MatsimServices;

import java.util.List;
import java.util.function.Predicate;

import static org.matsim.utils.gis.shp2matsim.ShpGeometryUtils.loadPreparedGeometries;
import static org.matsim.utils.gis.shp2matsim.ShpGeometryUtils.loadPreparedPolygons;

/**
* @author Michal Maciejewski (michalm)
*/
Expand All @@ -63,53 +46,11 @@ public void install() {
if (drtCfg.getZonalSystemParams().isPresent()) {
DrtZoneSystemParams params = drtCfg.getZonalSystemParams().get();
ZoneSystemParams zoneSystemParams = params.getZoneSystemParams();
String crs = getConfig().global().getCoordinateSystem();

bindModal(ZoneSystem.class).toProvider(modalProvider(getter -> {
Network network = getter.getModal(Network.class);
switch (zoneSystemParams.getName()) {
case GISFileZoneSystemParams.SET_NAME: {
Preconditions.checkNotNull(((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile);
final List<PreparedPolygon> preparedGeometries = loadPreparedPolygons(
ConfigGroup.getInputFileURL(getConfig().getContext(), ((GISFileZoneSystemParams) zoneSystemParams).zonesShapeFile));
return ZoneSystemUtils.createFromPreparedGeometries(network,
EntryStream.of(preparedGeometries).mapKeys(i -> (i + 1) + "").toMap());
}

case SquareGridZoneSystemParams.SET_NAME: {
Preconditions.checkNotNull(((SquareGridZoneSystemParams) zoneSystemParams).cellSize);
Predicate<Zone> zoneFilter;
if(drtCfg.operationalScheme == DrtConfigGroup.OperationalScheme.serviceAreaBased) {
List<PreparedGeometry> serviceAreas = loadPreparedGeometries(ConfigGroup.getInputFileURL(getConfig().getContext(),
drtCfg.drtServiceAreaShapeFile));
zoneFilter = zone -> serviceAreas.stream().anyMatch(serviceArea -> serviceArea.intersects(zone.getPreparedGeometry().getGeometry()));
} else {
zoneFilter = zone -> true;
}

SquareGridZoneSystem squareGridZoneSystem = new SquareGridZoneSystem(network, ((SquareGridZoneSystemParams) zoneSystemParams).cellSize, zoneFilter);
return squareGridZoneSystem;
}

case H3GridZoneSystemParams.SET_NAME: {

Preconditions.checkNotNull(((H3GridZoneSystemParams) zoneSystemParams).h3Resolution);
String crs = getConfig().global().getCoordinateSystem();

Predicate<Zone> zoneFilter;
if (drtCfg.operationalScheme == DrtConfigGroup.OperationalScheme.serviceAreaBased) {
List<PreparedGeometry> serviceAreas = loadPreparedGeometries(ConfigGroup.getInputFileURL(getConfig().getContext(),
drtCfg.drtServiceAreaShapeFile));
zoneFilter = zone -> serviceAreas.stream().anyMatch(serviceArea -> serviceArea.intersects(zone.getPreparedGeometry().getGeometry()));
} else {
zoneFilter = zone -> true;
}

return new H3ZoneSystem(crs, ((H3GridZoneSystemParams) zoneSystemParams).h3Resolution, network, zoneFilter);
}

default:
throw new RuntimeException("Unsupported zone generation");
}
return ZoneSystemUtils.createZoneSystem(getConfig().getContext(), network, zoneSystemParams, crs);
})).asEagerSingleton();

bindModal(DrtZoneTargetLinkSelector.class).toProvider(modalProvider(getter -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.PopulationComparison;
import org.matsim.testcases.MatsimTestUtils;
import org.matsim.utils.eventsfilecomparison.ComparisonResult;

Expand All @@ -33,8 +34,8 @@ public class RunEvExampleTest{
Population actual = PopulationUtils.createPopulation( ConfigUtils.createConfig() ) ;
PopulationUtils.readPopulation( actual, utils.getOutputDirectory() + "/output_plans.xml.gz" );

boolean result = PopulationUtils.comparePopulations( expected, actual );
Assertions.assertTrue(result);
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}
{
String expected = utils.getInputDirectory() + "/output_events.xml.gz" ;
Expand Down Expand Up @@ -66,8 +67,8 @@ public class RunEvExampleTest{
Population actual = PopulationUtils.createPopulation( ConfigUtils.createConfig() ) ;
PopulationUtils.readPopulation( actual, utils.getOutputDirectory() + "/output_plans.xml.gz" );

boolean result = PopulationUtils.comparePopulations( expected, actual );
Assertions.assertTrue(result);
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}
{
String expected = utils.getInputDirectory() + "/output_events.xml.gz" ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.PopulationComparison;
import org.matsim.testcases.MatsimTestUtils;
import org.matsim.utils.eventsfilecomparison.ComparisonResult;

Expand All @@ -33,8 +34,8 @@ void runTest(){
Population actual = PopulationUtils.createPopulation( ConfigUtils.createConfig() ) ;
PopulationUtils.readPopulation( actual, utils.getOutputDirectory() + "/output_plans.xml.gz" );

boolean result = PopulationUtils.comparePopulations( expected, actual );
Assertions.assertTrue( result );
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}
{
String expected = utils.getInputDirectory() + "/output_events.xml.gz" ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void runChessboard() {
Population actual = PopulationUtils.createPopulation( ConfigUtils.createConfig() ) ;
PopulationUtils.readPopulation( actual, utils.getOutputDirectory() + "/output_plans.xml.gz" );

PopulationComparison.Result result = new PopulationComparison().compare(expected, actual);
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertSame(PopulationComparison.Result.equal, result);
}
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.api.core.v01.population.Population;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.PopulationComparison;
import org.matsim.core.utils.io.IOUtils;
import org.matsim.examples.ExamplesUtils;
import org.matsim.testcases.MatsimTestUtils;
Expand Down Expand Up @@ -60,9 +62,8 @@ void testMain(){
PopulationUtils.readPopulation( expected, utils.getInputDirectory() + "/output_experienced_plans.xml.gz" );
final Population actual = PopulationUtils.createPopulation( ConfigUtils.createConfig() );
PopulationUtils.readPopulation( actual, utils.getOutputDirectory() + "/output_experienced_plans.xml.gz" );
if(!PopulationUtils.comparePopulations( expected, actual )) {
throw new RuntimeException("Plans file comparison ended with result false");
}
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void install() {
PopulationUtils.readPopulation( popExpected, utils.getInputDirectory() + "/output_plans.xml.gz" );
Population popActual = PopulationUtils.createPopulation( config );
PopulationUtils.readPopulation( popActual, outDir + "/output_plans.xml.gz" );
new PopulationComparison().compare( popExpected, popActual ) ;
PopulationComparison.compare( popExpected, popActual ) ;
Assertions.assertEquals(138.86084460860525, psimScore, MatsimTestUtils.EPSILON, "RunPsim score changed.");

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.PopulationComparison;
import org.matsim.core.utils.io.IOUtils;
import org.matsim.examples.ExamplesUtils;
import org.matsim.testcases.MatsimTestUtils;
Expand Down Expand Up @@ -62,7 +63,8 @@ final void testMain() {
PopulationUtils.readPopulation( expected, utils.getInputDirectory() + "/output_plans.xml.gz" );
final Population actual = PopulationUtils.createPopulation( ConfigUtils.createConfig() );
PopulationUtils.readPopulation( actual, utils.getOutputDirectory() + "/output_plans.xml.gz" );
Assertions.assertTrue(PopulationUtils.comparePopulations( expected, actual ), "Populations are different");
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ private void runScenario(String configPath) {
Population actual = PopulationUtils.createPopulation(ConfigUtils.createConfig());
PopulationUtils.readPopulation(actual, utils.getOutputDirectory() + "/output_plans.xml.gz");

PopulationComparison populationComparison = new PopulationComparison();
PopulationComparison.Result result = populationComparison.compare(expected, actual);
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ public static void runBenchmark(boolean vehicleDiversion, AbstractTaxiOptimizerP
Population actual = PopulationUtils.createPopulation(ConfigUtils.createConfig());
PopulationUtils.readPopulation(actual, utils.getOutputDirectory() + "/output_plans.xml.gz");

PopulationComparison populationComparison = new PopulationComparison();
PopulationComparison.Result result = populationComparison.compare(expected, actual);
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}
{
Expand Down
5 changes: 3 additions & 2 deletions contribs/vsp/src/test/java/playground/vsp/ev/UrbanEVIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.PopulationComparison;
import org.matsim.testcases.MatsimTestUtils;
import org.matsim.utils.eventsfilecomparison.ComparisonResult;

Expand All @@ -32,8 +33,8 @@ void run() {
Population actual = PopulationUtils.createPopulation( ConfigUtils.createConfig() ) ;
PopulationUtils.readPopulation( actual, utils.getOutputDirectory() + "/output_plans.xml.gz" );

boolean result = PopulationUtils.comparePopulations( expected, actual );
Assertions.assertTrue( result );
PopulationComparison.Result result = PopulationComparison.compare(expected, actual);
Assertions.assertEquals(PopulationComparison.Result.equal, result);
}
{
String expected = utils.getInputDirectory() + "/output_events.xml.gz" ;
Expand Down
Loading
Loading