diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java index e5b6a27b774..57328df62cc 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java @@ -26,7 +26,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.config.Configurator; -import org.locationtech.jts.geom.Geometry; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -62,7 +61,8 @@ import org.matsim.core.scoring.SumScoringFunction; import org.matsim.core.utils.geometry.CoordUtils; import org.matsim.core.utils.geometry.CoordinateTransformation; -import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.facilities.ActivityFacilities; +import org.matsim.facilities.ActivityFacility; import org.matsim.freight.carriers.*; import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; import org.matsim.freight.carriers.controler.*; @@ -82,6 +82,7 @@ import java.util.stream.Collectors; import static org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles; +import static org.matsim.smallScaleCommercialTrafficGeneration.SmallScaleCommercialTrafficUtils.readDataDistribution; /** * Tool to generate small scale commercial traffic for a selected area. The needed input data are: employee information for the area and three shapes files (zones, buildings, landuse). These data should be available with OSM. @@ -106,10 +107,6 @@ private enum CreationOption { useExistingCarrierFileWithSolution, createNewCarrierFile, useExistingCarrierFileWithoutSolution } - private enum LanduseConfiguration { - useOnlyOSMLanduse, useOSMBuildingsAndLanduse, useExistingDataDistribution - } - private enum SmallScaleCommercialTrafficType { commercialPersonTraffic, goodsTraffic, completeSmallScaleCommercialTraffic } @@ -117,11 +114,11 @@ private enum SmallScaleCommercialTrafficType { @CommandLine.Parameters(arity = "1", paramLabel = "INPUT", description = "Path to the config for small scale commercial generation") private Path configPath; - @CommandLine.Option(names = "--pathToInvestigationAreaData", description = "Path to the investigation area data") - private Path pathToInvestigationAreaData; + @CommandLine.Option(names = "--pathToDataDistributionToZones", description = "Path to the data distribution to zones") + private Path pathToDataDistributionToZones; - @CommandLine.Option(names = "--pathToExistingDataDistributionToZones", description = "Path to the existing data distribution to zones. This is only needed if the option useExistingDataDistribution is selected.") - private Path pathToExistingDataDistributionToZones; + @CommandLine.Option(names = "--pathToCommercialFacilities", description = "Path to the commercial facilities.") + private Path pathToCommercialFacilities; @CommandLine.Option(names = "--sample", description = "Scaling factor of the small scale commercial traffic (0, 1)", required = true) private double sample; @@ -184,13 +181,9 @@ private enum SmallScaleCommercialTrafficType { private Path output; private Random rnd; - private final Map>> buildingsPerZone = new HashMap<>(); - private final Map> landuseCategoriesAndDataConnection = new HashMap<>(); + private final Map>> facilitiesPerZone = new HashMap<>(); private Index indexZones; - private Index indexBuildings; - private Index indexLanduse; - private Index indexInvestigationAreaRegions; public static void main(String[] args) { System.exit(new CommandLine(new GenerateSmallScaleCommercialTrafficDemand()).execute(args)); @@ -237,31 +230,14 @@ public Integer call() throws Exception { solveSeparatedVRPs(scenario, null); } default -> { - if (!Files.exists(shapeFileLandusePath)) { - throw new Exception("Required landuse shape file not found:" + shapeFileLandusePath.toString()); - } - if (!Files.exists(shapeFileBuildingsPath)) { - throw new Exception( - "Required OSM buildings shape file {} not found" + shapeFileBuildingsPath.toString()); - } if (!Files.exists(shapeFileZonePath)) { throw new Exception("Required districts shape file {} not found" + shapeFileZonePath.toString()); } - if (!Files.exists(shapeFileRegionsPath)) { - throw new Exception("Required regions shape file {} not found" + shapeFileRegionsPath.toString()); - } - indexZones = SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shapeCRS, shapeFileZoneNameColumn); - indexBuildings = SmallScaleCommercialTrafficUtils.getIndexBuildings(shapeFileBuildingsPath, shapeCRS, shapeFileBuildingTypeColumn); - indexLanduse = SmallScaleCommercialTrafficUtils.getIndexLanduse(shapeFileLandusePath, shapeCRS, shapeFileLanduseTypeColumn); - indexInvestigationAreaRegions = SmallScaleCommercialTrafficUtils.getIndexRegions(shapeFileRegionsPath, shapeCRS, regionsShapeRegionColumn); - Map> resultingDataPerZone = LanduseBuildingAnalysis - .createInputDataDistribution(output, landuseCategoriesAndDataConnection, - usedLanduseConfiguration.toString(), indexLanduse, indexZones, - indexBuildings, indexInvestigationAreaRegions, shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, - pathToExistingDataDistributionToZones); - Map, Link>> linksPerZone = filterLinksForZones(scenario, indexZones, buildingsPerZone); + Map> resultingDataPerZone = readDataDistribution(pathToDataDistributionToZones); + filterFacilitiesForZones(scenario, facilitiesPerZone); + Map, Link>> linksPerZone = filterLinksForZones(scenario, indexZones, facilitiesPerZone); switch (usedSmallScaleCommercialTrafficType) { case commercialPersonTraffic, goodsTraffic -> @@ -311,11 +287,24 @@ public Integer call() throws Exception { return 0; } + /** Creates + * @param scenario + * @param facilitiesPerZone + */ + private void filterFacilitiesForZones(Scenario scenario, Map>> facilitiesPerZone) { + scenario.getActivityFacilities().getFacilities().values().forEach((activityFacility -> { + activityFacility.getActivityOptions().values().forEach(activityOption -> { + facilitiesPerZone.computeIfAbsent((String) activityFacility.getAttributes().getAttribute("zone"), k -> new HashMap<>()) + .computeIfAbsent(activityOption.getType(), k -> new ArrayList<>()).add(activityFacility); + }); + })); + } + /** * @param originalScenario complete Scenario - * @param regionLinksMap list with Links for each region + * @param linksPerZone list with Links for each region */ - private void solveSeparatedVRPs(Scenario originalScenario, Map, Link>> regionLinksMap) throws Exception { + private void solveSeparatedVRPs(Scenario originalScenario, Map, Link>> linksPerZone) throws Exception { boolean splitCarrier = true; boolean splitVRPs = false; @@ -432,11 +421,11 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map { - if (regionLinksMap != null && !carrier.getAttributes().getAsMap().containsKey("tourStartArea")) { + if (linksPerZone != null && !carrier.getAttributes().getAsMap().containsKey("tourStartArea")) { List startAreas = new ArrayList<>(); for (ScheduledTour tour : carrier.getSelectedPlan().getScheduledTours()) { String tourStartZone = SmallScaleCommercialTrafficUtils - .findZoneOfLink(tour.getTour().getStartLinkId(), regionLinksMap); + .findZoneOfLink(tour.getTour().getStartLinkId(), linksPerZone); if (!startAreas.contains(tourStartZone)) startAreas.add(tourStartZone); } @@ -498,7 +487,7 @@ private Config readAndCheckConfig(Path configPath, String modelName, String samp config.transit().setTransitScheduleFile(null); config.transit().setVehiclesFile(null); config.counts().setInputFile(null); - + config.facilities().setInputFile(pathToCommercialFacilities.toString()); // Set flow and storage capacity to a high value config.qsim().setFlowCapFactor(sample * 4); config.qsim().setStorageCapFactor(sample * 4); @@ -553,7 +542,7 @@ public void install() { */ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, Map> resultingDataPerZone, String smallScaleCommercialTrafficType, - Map, Link>> regionLinksMap) { + Map, Link>> linksPerZone) { int maxNumberOfCarrier = odMatrix.getListOfPurposes().size() * odMatrix.getListOfZones().size() * odMatrix.getListOfModesOrVehTypes().size(); int createdCarrier = 0; @@ -689,7 +678,7 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, purpose, smallScaleCommercialTrafficType) / occupancyRate)); createNewCarrierAndAddVehicleTypes(scenario, purpose, startZone, selectedStartCategory, carrierName, vehicleTypes, numberOfDepots, fleetSize, - fixedNumberOfVehiclePerTypeAndLocation, vehicleDepots, regionLinksMap, smallScaleCommercialTrafficType, + fixedNumberOfVehiclePerTypeAndLocation, vehicleDepots, linksPerZone, smallScaleCommercialTrafficType, tourStartTimeSelector, tourDurationTimeSelector); log.info("Create services for carrier: " + carrierName); for (String stopZone : odMatrix.getListOfZones()) { @@ -712,7 +701,7 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, TimeWindow serviceTimeWindow = TimeWindow.newInstance(0, 24 * 3600); //TODO eventuell anpassen wegen veränderter Tourzeiten createServices(scenario, vehicleDepots, selectedStopCategory, carrierName, - numberOfJobs, serviceArea, serviceTimePerStop, serviceTimeWindow, regionLinksMap); + numberOfJobs, serviceArea, serviceTimePerStop, serviceTimeWindow, linksPerZone); } } } @@ -739,13 +728,13 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, private void createServices(Scenario scenario, ArrayList noPossibleLinks, String selectedStopCategory, String carrierName, int numberOfJobs, String[] serviceArea, Integer serviceTimePerStop, TimeWindow serviceTimeWindow, - Map, Link>> regionLinksMap) { + Map, Link>> linksPerZone) { String stopZone = serviceArea[0]; for (int i = 0; i < numberOfJobs; i++) { - Id linkId = findPossibleLink(stopZone, selectedStopCategory, noPossibleLinks, regionLinksMap); + Id linkId = findPossibleLink(stopZone, selectedStopCategory, noPossibleLinks, linksPerZone, scenario.getActivityFacilities()); Id idNewService = Id.create(carrierName + "_" + linkId + "_" + rnd.nextInt(10000), CarrierService.class); @@ -764,7 +753,7 @@ private void createNewCarrierAndAddVehicleTypes(Scenario scenario, Integer purpo String selectedStartCategory, String carrierName, List vehicleTypes, int numberOfDepots, FleetSize fleetSize, int fixedNumberOfVehiclePerTypeAndLocation, - List vehicleDepots, Map, Link>> regionLinksMap, + List vehicleDepots, Map, Link>> linksPerZone, String smallScaleCommercialTrafficType, ValueSelectorUnderGivenProbability tourStartTimeSelector, ValueSelectorUnderGivenProbability tourDurationTimeSelector) { @@ -788,7 +777,7 @@ private void createNewCarrierAndAddVehicleTypes(Scenario scenario, Integer purpo carriers.addCarrier(thisCarrier); while (vehicleDepots.size() < numberOfDepots) { - Id link = findPossibleLink(startZone, selectedStartCategory, null, regionLinksMap); + Id link = findPossibleLink(startZone, selectedStartCategory, null, linksPerZone, scenario.getActivityFacilities()); vehicleDepots.add(link.toString()); } @@ -877,31 +866,25 @@ else if (smallScaleCommercialTrafficType.equals(SmallScaleCommercialTrafficType. * Finds a possible link for a service or the vehicle location. */ private Id findPossibleLink(String zone, String selectedCategory, List noPossibleLinks, - Map, Link>> regionLinksMap) { + Map, Link>> linksPerZone, ActivityFacilities activityFacilities) { - if (buildingsPerZone.isEmpty()) { - List buildingsFeatures = indexBuildings.getAllFeatures(); - LanduseBuildingAnalysis.analyzeBuildingType(buildingsFeatures, buildingsPerZone, - landuseCategoriesAndDataConnection, indexLanduse, indexZones); - } Id newLink = null; - for (int a = 0; newLink == null && a < buildingsPerZone.get(zone).get(selectedCategory).size() * 2; a++) { + for (int a = 0; newLink == null && a < facilitiesPerZone.get(zone).get(selectedCategory).size() * 2; a++) { - SimpleFeature possibleBuilding = buildingsPerZone.get(zone).get(selectedCategory) - .get(rnd.nextInt(buildingsPerZone.get(zone).get(selectedCategory).size())); - Coord centroidPointOfBuildingPolygon = MGC - .point2Coord(((Geometry) possibleBuilding.getDefaultGeometry()).getCentroid()); + ActivityFacility possibleBuilding = facilitiesPerZone.get(zone).get(selectedCategory) + .get(rnd.nextInt(facilitiesPerZone.get(zone).get(selectedCategory).size())); //TODO Wkt für die Auswahl anpassen + Coord centroidPointOfBuildingPolygon = possibleBuilding.getCoord(); - int numberOfPossibleLinks = regionLinksMap.get(zone).size(); + int numberOfPossibleLinks = linksPerZone.get(zone).size(); // searches and selects the nearest link of the possible links in this zone - newLink = SmallScaleCommercialTrafficUtils.findNearestPossibleLink(zone, noPossibleLinks, regionLinksMap, newLink, + newLink = SmallScaleCommercialTrafficUtils.findNearestPossibleLink(zone, noPossibleLinks, linksPerZone, newLink, centroidPointOfBuildingPolygon, numberOfPossibleLinks); } if (newLink == null) throw new RuntimeException("No possible link for buildings with type '" + selectedCategory + "' in zone '" - + zone + "' found. buildings in category: " + buildingsPerZone.get(zone).get(selectedCategory) - + "; possibleLinks in zone: " + regionLinksMap.get(zone).size()); + + zone + "' found. buildings in category: " + facilitiesPerZone.get(zone).get(selectedCategory) + + "; possibleLinks in zone: " + linksPerZone.get(zone).size()); return newLink; } @@ -909,8 +892,8 @@ private Id findPossibleLink(String zone, String selectedCategory, List, Link>> filterLinksForZones(Scenario scenario, Index indexZones, - Map>> buildingsPerZone) throws URISyntaxException { - Map, Link>> regionLinksMap = new HashMap<>(); + Map>> facilitiesPerZone) throws URISyntaxException { + Map, Link>> linksPerZone = new HashMap<>(); List links; log.info("Filtering and assign links to zones. This take some time..."); @@ -932,30 +915,29 @@ static Map, Link>> filterLinksForZones(Scenario scenario, I links.forEach(l -> l.getAttributes().putAttribute("zone", indexZones.query((Coord) l.getAttributes().getAttribute("newCoord")))); links = links.stream().filter(l -> l.getAttributes().getAttribute("zone") != null).collect(Collectors.toList()); - links.forEach(l -> regionLinksMap + links.forEach(l -> linksPerZone .computeIfAbsent((String) l.getAttributes().getAttribute("zone"), (k) -> new HashMap<>()) .put(l.getId(), l)); - if (regionLinksMap.size() != indexZones.size()) - findNearestLinkForZonesWithoutLinks(networkToChange, regionLinksMap, indexZones, buildingsPerZone); + if (linksPerZone.size() != indexZones.size()) + findNearestLinkForZonesWithoutLinks(networkToChange, linksPerZone, indexZones, facilitiesPerZone); - return regionLinksMap; + return linksPerZone; } /** * Finds for areas without links the nearest Link if the area contains any building. */ - private static void findNearestLinkForZonesWithoutLinks(Network networkToChange, Map, Link>> regionLinksMap, + private static void findNearestLinkForZonesWithoutLinks(Network networkToChange, Map, Link>> linksPerZone, Index shpZones, - Map>> buildingsPerZone) { + Map>> facilitiesPerZone) { for (SimpleFeature singleArea : shpZones.getAllFeatures()) { String zoneID = (String) singleArea.getAttribute("areaID"); - if (!regionLinksMap.containsKey(zoneID) && buildingsPerZone.get(zoneID) != null) { - for (List buildingList : buildingsPerZone.get(zoneID).values()) { - for (SimpleFeature building : buildingList) { - Link l = NetworkUtils.getNearestLink(networkToChange, - MGC.point2Coord(((Geometry) building.getDefaultGeometry()).getCentroid())); + if (!linksPerZone.containsKey(zoneID) && facilitiesPerZone.get(zoneID) != null) { + for (List buildingList : facilitiesPerZone.get(zoneID).values()) { + for (ActivityFacility building : buildingList) { + Link l = NetworkUtils.getNearestLink(networkToChange, building.getCoord()); assert l != null; - regionLinksMap + linksPerZone .computeIfAbsent(zoneID, (k) -> new HashMap<>()) .put(l.getId(), l); } @@ -970,7 +952,7 @@ private static void findNearestLinkForZonesWithoutLinks(Network networkToChange, private TripDistributionMatrix createTripDistribution( Map> trafficVolume_start, Map> trafficVolume_stop, - String smallScaleCommercialTrafficType, Scenario scenario, Path output, Map, Link>> regionLinksMap) + String smallScaleCommercialTrafficType, Scenario scenario, Path output, Map, Link>> linksPerZone) throws Exception { ArrayList listOfZones = new ArrayList<>(); @@ -994,7 +976,7 @@ private TripDistributionMatrix createTripDistribution( Collections.shuffle(listOfZones, rnd); for (String stopZone : listOfZones) { odMatrix.setTripDistributionValue(startZone, stopZone, modeORvehType, purpose, smallScaleCommercialTrafficType, - network, regionLinksMap, resistanceFactor, shapeFileZoneNameColumn); + network, linksPerZone, resistanceFactor, shapeFileZoneNameColumn); } } } diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java index f00dcd020e5..965b8387228 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtils.java @@ -19,7 +19,6 @@ * *********************************************************************** */ package org.matsim.smallScaleCommercialTrafficGeneration; -import com.google.common.base.Joiner; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.solution.SolutionCostCalculator; @@ -28,6 +27,7 @@ import com.graphhopper.jsprit.core.problem.solution.route.activity.BreakActivity; import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; import it.unimi.dsi.fastutil.objects.Object2DoubleMap; +import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; @@ -40,24 +40,23 @@ import org.matsim.api.core.v01.population.*; import org.matsim.application.options.ShpOptions; import org.matsim.application.options.ShpOptions.Index; +import org.matsim.core.gbl.MatsimRandom; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.population.PopulationUtils; +import org.matsim.core.utils.io.IOUtils; import org.matsim.freight.carriers.*; import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; import org.matsim.freight.carriers.Tour.Pickup; import org.matsim.freight.carriers.Tour.ServiceActivity; import org.matsim.freight.carriers.Tour.TourElement; import org.matsim.freight.carriers.jsprit.MatsimJspritFactory; -import org.matsim.core.gbl.MatsimRandom; -import org.matsim.core.network.NetworkUtils; -import org.matsim.core.population.PopulationUtils; -import org.matsim.core.utils.io.IOUtils; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; import org.matsim.vehicles.Vehicles; -import java.io.BufferedWriter; +import java.io.BufferedReader; import java.io.IOException; -import java.net.MalformedURLException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -72,7 +71,6 @@ public class SmallScaleCommercialTrafficUtils { private static final Logger log = LogManager.getLogger(SmallScaleCommercialTrafficUtils.class); - private static final Joiner JOIN = Joiner.on("\t"); /** * Creates and return the Index of the zone shape. @@ -82,7 +80,7 @@ public class SmallScaleCommercialTrafficUtils { * @param shapeFileZoneNameColumn Column name of the zone in the shape file * @return indexZones */ - static Index getIndexZones(Path shapeFileZonePath, String shapeCRS, String shapeFileZoneNameColumn) { + public static Index getIndexZones(Path shapeFileZonePath, String shapeCRS, String shapeFileZoneNameColumn) { ShpOptions shpZones = new ShpOptions(shapeFileZonePath, shapeCRS, StandardCharsets.UTF_8); if (shpZones.readFeatures().iterator().next().getAttribute(shapeFileZoneNameColumn) == null) @@ -98,7 +96,7 @@ static Index getIndexZones(Path shapeFileZonePath, String shapeCRS, String shape * @param shapeFileLanduseTypeColumn Column name of the landuse in the shape file * @return indexLanduse */ - static Index getIndexLanduse(Path shapeFileLandusePath, String shapeCRS, String shapeFileLanduseTypeColumn) { + public static Index getIndexLanduse(Path shapeFileLandusePath, String shapeCRS, String shapeFileLanduseTypeColumn) { ShpOptions shpLanduse = new ShpOptions(shapeFileLandusePath, shapeCRS, StandardCharsets.UTF_8); if (shpLanduse.readFeatures().iterator().next().getAttribute(shapeFileLanduseTypeColumn) == null) throw new NullPointerException("The column '" + shapeFileLanduseTypeColumn + "' does not exist in the landuse shape file. Please check the input."); @@ -113,7 +111,7 @@ static Index getIndexLanduse(Path shapeFileLandusePath, String shapeCRS, String * @param shapeFileBuildingTypeColumn Column name of the building in the shape file * @return indexBuildings */ - static Index getIndexBuildings(Path shapeFileBuildingsPath, String shapeCRS, String shapeFileBuildingTypeColumn) { + public static Index getIndexBuildings(Path shapeFileBuildingsPath, String shapeCRS, String shapeFileBuildingTypeColumn) { ShpOptions shpBuildings = new ShpOptions(shapeFileBuildingsPath, shapeCRS, StandardCharsets.UTF_8); if (shpBuildings.readFeatures().iterator().next().getAttribute(shapeFileBuildingTypeColumn) == null) throw new NullPointerException("The column '" + shapeFileBuildingTypeColumn + "' does not exist in the building shape file. Please check the input."); @@ -136,17 +134,6 @@ public static Index getIndexRegions(Path shapeFileRegionsPath, String shapeCRS, return shpRegions.createIndex(shapeCRS, regionsShapeRegionColumn); } - /** - * Writes a csv file with the result of the distribution per zone of the input data. - */ - static void writeResultOfDataDistribution(Map> resultingDataPerZone, - Path outputFileInOutputFolder, Map zoneIdRegionConnection) - throws IOException { - - writeCSVWithCategoryHeader(resultingDataPerZone, outputFileInOutputFolder, zoneIdRegionConnection); - log.info("The data distribution is finished and written to: " + outputFileInOutputFolder); - } - /** Finds the nearest possible link for the building polygon. * @param zone * @param noPossibleLinks @@ -191,39 +178,6 @@ static Id findNearestPossibleLink(String zone, List noPossibleLink return newLink; } - /** - * Writer of data distribution data. - */ - private static void writeCSVWithCategoryHeader(Map> resultingDataPerZone, - Path outputFileInInputFolder, - Map zoneIdRegionConnection) throws MalformedURLException { - BufferedWriter writer = IOUtils.getBufferedWriter(outputFileInInputFolder.toUri().toURL(), - StandardCharsets.UTF_8, true); - try { - String[] header = new String[]{"zoneID", "region", "Inhabitants", "Employee", "Employee Primary Sector", - "Employee Construction", "Employee Secondary Sector Rest", "Employee Retail", - "Employee Traffic/Parcels", "Employee Tertiary Sector Rest"}; - JOIN.appendTo(writer, header); - writer.write("\n"); - for (String zone : resultingDataPerZone.keySet()) { - List row = new ArrayList<>(); - row.add(zone); - row.add(zoneIdRegionConnection.get(zone)); - for (String category : header) { - if (!category.equals("zoneID") && !category.equals("region")) - row.add(String.valueOf((int) Math.round(resultingDataPerZone.get(zone).getDouble(category)))); - } - JOIN.appendTo(writer, row); - writer.write("\n"); - } - - writer.close(); - - } catch (IOException e) { - log.error("Could not write the csv file with the data distribution data.", e); - } - } - /** * Creates a population including the plans in preparation for the MATSim run. If a different name of the population is set, different plan variants per person are created */ @@ -571,6 +525,37 @@ static String findZoneOfLink(Id linkId, Map, Link>> l return null; } + + /** TODO + * @param pathToDataDistributionToZones + * @return + * @throws IOException + */ + static Map> readDataDistribution(Path pathToDataDistributionToZones) throws IOException { + if (!Files.exists(pathToDataDistributionToZones)) { + log.error("Required data per zone file {} not found", pathToDataDistributionToZones); + } + + Map> resultingDataPerZone = new HashMap<>(); + try (BufferedReader reader = IOUtils.getBufferedReader(pathToDataDistributionToZones.toString())) { + CSVParser parse = CSVFormat.Builder.create(CSVFormat.DEFAULT).setDelimiter('\t').setHeader() + .setSkipHeaderRecord(true).build().parse(reader); + + for (CSVRecord record : parse) { + String zoneID = record.get("zoneID"); + resultingDataPerZone.put(zoneID, new Object2DoubleOpenHashMap<>()); + for (int n = 2; n < parse.getHeaderMap().size(); n++) { + resultingDataPerZone.get(zoneID).mergeDouble(parse.getHeaderNames().get(n), + Double.parseDouble(record.get(n)), Double::sum); + } + } + } + log.info("Data distribution for " + resultingDataPerZone.size() + " zones was read from " + + pathToDataDistributionToZones); + return resultingDataPerZone; + + } + /** * Creates a cost calculator. */ diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/CreateDataDistributionOfStructureData.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/CreateDataDistributionOfStructureData.java new file mode 100644 index 00000000000..07255fc367f --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/CreateDataDistributionOfStructureData.java @@ -0,0 +1,151 @@ +package org.matsim.smallScaleCommercialTrafficGeneration.prepare; + +import it.unimi.dsi.fastutil.objects.Object2DoubleMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.locationtech.jts.geom.Geometry; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.application.MATSimAppCommand; +import org.matsim.application.options.ShpOptions; +import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.facilities.*; +import org.matsim.smallScaleCommercialTrafficGeneration.SmallScaleCommercialTrafficUtils; +import org.opengis.feature.simple.SimpleFeature; +import picocli.CommandLine; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.matsim.smallScaleCommercialTrafficGeneration.prepare.LanduseBuildingAnalysis.*; + +@CommandLine.Command(name = "create-data-distribution-of-structure-data", description = "Create data distribution as preperation for the generation of small scale commercial traffic", showDefaultValues = true) +public class CreateDataDistributionOfStructureData implements MATSimAppCommand { + + private static final Logger log = LogManager.getLogger(CreateDataDistributionOfStructureData.class); + + private enum LanduseConfiguration { + useOnlyOSMLanduse, useOSMBuildingsAndLanduse + } + + @CommandLine.Option(names = "--pathOutput", description = "Path for the output", defaultValue = "output/TestDistributionClass") + private Path output; + + @CommandLine.Option(names = "--landuseConfiguration", description = "Set option of used OSM data. Options: useOnlyOSMLanduse, useOSMBuildingsAndLanduse, useExistingDataDistribution", defaultValue = "useOSMBuildingsAndLanduse") + private LanduseConfiguration usedLanduseConfiguration; + + @CommandLine.Option(names = "--regionsShapeFileName", description = "Path of the region shape file.", defaultValue = "contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/shp/testRegions.shp") + private Path shapeFileRegionsPath; + + @CommandLine.Option(names = "--regionsShapeRegionColumn", description = "Name of the region column in the region shape file.", defaultValue = "region") + private String regionsShapeRegionColumn; + + @CommandLine.Option(names = "--zoneShapeFileName", description = "Path of the zone shape file.", defaultValue = "contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/shp/testZones.shp") + private Path shapeFileZonePath; + + @CommandLine.Option(names = "--zoneShapeFileNameColumn", description = "Name of the unique column of the name/Id of each zone in the zones shape file.", defaultValue = "name") + private String shapeFileZoneNameColumn; + + @CommandLine.Option(names = "--buildingsShapeFileName", description = "Path of the buildings shape file", defaultValue = "contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/shp/testBuildings.shp") + private Path shapeFileBuildingsPath; + + @CommandLine.Option(names = "--shapeFileBuildingTypeColumn", description = "Name of the unique column of the building type in the buildings shape file.", defaultValue = "type") + private String shapeFileBuildingTypeColumn; + + @CommandLine.Option(names = "--landuseShapeFileName", description = "Path of the landuse shape file", defaultValue = "contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/shp/testLanduse.shp") + private Path shapeFileLandusePath; + + @CommandLine.Option(names = "--shapeFileLanduseTypeColumn", description = "Name of the unique column of the landuse type in the landuse shape file.", defaultValue = "fclass") + private String shapeFileLanduseTypeColumn; + + @CommandLine.Option(names = "--shapeCRS", description = "CRS of the three input shape files (zones, landuse, buildings", defaultValue = "EPSG:4326") + private String shapeCRS; + + @CommandLine.Option(names = "--pathToInvestigationAreaData", description = "Path to the investigation area data", defaultValue = "contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/investigationAreaData.csv") + private Path pathToInvestigationAreaData; + + private final Map> landuseCategoriesAndDataConnection = new HashMap<>(); + private final Map>> buildingsPerZone = new HashMap<>(); + + private ShpOptions.Index indexZones; + private ShpOptions.Index indexBuildings; + private ShpOptions.Index indexLanduse; + private ShpOptions.Index indexInvestigationAreaRegions; + + public static void main(String[] args) { + System.exit(new CommandLine(new CreateDataDistributionOfStructureData()).execute(args)); + } + + @Override + public Integer call() throws Exception { + log.info("Create data distribution of structure data"); + + if (!Files.exists(shapeFileLandusePath)) { + throw new Exception("Required landuse shape file not found:" + shapeFileLandusePath.toString()); + } + if (!Files.exists(shapeFileBuildingsPath)) { + throw new Exception( + "Required OSM buildings shape file {} not found" + shapeFileBuildingsPath.toString()); + } + if (!Files.exists(shapeFileZonePath)) { + throw new Exception("Required districts shape file {} not found" + shapeFileZonePath.toString()); + } + if (!Files.exists(shapeFileRegionsPath)) { + throw new Exception("Required regions shape file {} not found" + shapeFileRegionsPath.toString()); + } + + indexZones = SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shapeCRS, shapeFileZoneNameColumn); + indexBuildings = SmallScaleCommercialTrafficUtils.getIndexBuildings(shapeFileBuildingsPath, shapeCRS, shapeFileBuildingTypeColumn); + indexLanduse = SmallScaleCommercialTrafficUtils.getIndexLanduse(shapeFileLandusePath, shapeCRS, shapeFileLanduseTypeColumn); + indexInvestigationAreaRegions = SmallScaleCommercialTrafficUtils.getIndexRegions(shapeFileRegionsPath, shapeCRS, regionsShapeRegionColumn); + + if(Files.notExists(output)) + new File(output.toString()).mkdir(); + + createDefaultDataConnectionForOSM(landuseCategoriesAndDataConnection); //TODO: find way to import this connection + + Map> resultingDataPerZone = LanduseBuildingAnalysis + .createInputDataDistribution(output, landuseCategoriesAndDataConnection, + usedLanduseConfiguration.toString(), indexLanduse, indexZones, + indexBuildings, indexInvestigationAreaRegions, shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); + + ActivityFacilities facilities = FacilitiesUtils.createActivityFacilities(); + + ActivityFacilitiesFactory f = facilities.getFactory(); + + for (String zone : buildingsPerZone.keySet()) { + for (String assignedDataType : buildingsPerZone.get(zone).keySet()) { + buildingsPerZone.get(zone).get(assignedDataType).forEach(singleBuilding -> { + Id id = Id.create(singleBuilding.getID(), ActivityFacility.class); + if (facilities.getFacilities().containsKey(id)) { + facilities.getFacilities().get(id).addActivityOption(f.createActivityOption(assignedDataType)); + } else { + Coord coord = MGC.point2Coord(((Geometry) singleBuilding.getDefaultGeometry()).getCentroid()); + ActivityFacility facility = f.createActivityFacility(id, coord); + facility.addActivityOption(f.createActivityOption(assignedDataType)); + String[] buildingTypes = ((String) singleBuilding.getAttribute("type")).split(";"); + int calculatedAreaPerBuildingCategory = calculateAreaPerBuildingCategory(singleBuilding, buildingTypes); + facility.getAttributes().putAttribute("shareOfZone_" + assignedDataType, + getShareOfTheBuildingAreaOfTheRelatedAreaOfTheZone(zone, calculatedAreaPerBuildingCategory, + assignedDataType)); //TODO: check if this is the right + //TODO Employee hat momentan noch infinity als Wert + facility.getAttributes().putAttribute("zone", zone); + facilities.addActivityFacility(facility); + } + }); + + } + } + Path facilityOutput = output.resolve("commercialFacilities.xml.gz"); + log.info("Created {} facilities, writing to {}", facilities.getFacilities().size(), facilityOutput); + + FacilitiesWriter writer = new FacilitiesWriter(facilities); + writer.write(facilityOutput.toString()); + + return 0; + } +} diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysis.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/LanduseBuildingAnalysis.java similarity index 70% rename from contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysis.java rename to contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/LanduseBuildingAnalysis.java index 7e26668438e..b9931fbbfbb 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysis.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/LanduseBuildingAnalysis.java @@ -17,8 +17,9 @@ * See also COPYING, LICENSE and WARRANTY file * * * * *********************************************************************** */ -package org.matsim.smallScaleCommercialTrafficGeneration; +package org.matsim.smallScaleCommercialTrafficGeneration.prepare; +import com.google.common.base.Joiner; import it.unimi.dsi.fastutil.objects.Object2DoubleMap; import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap; import org.apache.commons.csv.CSVFormat; @@ -34,11 +35,12 @@ import org.matsim.core.utils.io.IOUtils; import org.opengis.feature.simple.SimpleFeature; -import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.*; /** @@ -48,87 +50,66 @@ public class LanduseBuildingAnalysis { private static final Logger log = LogManager.getLogger(LanduseBuildingAnalysis.class); + private static final Joiner JOIN = Joiner.on("\t"); + static Map> resultingSumsForZones = new HashMap<>(); /** * Creates a distribution of the given input data for each zone based on the * used OSM data. */ - static Map> createInputDataDistribution(Path output, - Map> landuseCategoriesAndDataConnection, - String usedLanduseConfiguration, Index indexLanduse, Index indexZones, - Index indexBuildings, Index indexInvestigationAreaRegions, - String shapeFileZoneNameColumn, - Map>> buildingsPerZone, - Path pathToInvestigationAreaData, - Path pathToExistingDataDistributionToZones) + public static Map> createInputDataDistribution(Path output, + Map> landuseCategoriesAndDataConnection, + String usedLanduseConfiguration, Index indexLanduse, + Index indexZones, + Index indexBuildings, Index indexInvestigationAreaRegions, + String shapeFileZoneNameColumn, + Map>> buildingsPerZone, + Path pathToInvestigationAreaData) throws IOException { Map> resultingDataPerZone = new HashMap<>(); Map zoneIdRegionConnection = new HashMap<>(); - Path outputFileInOutputFolder = output.resolve("calculatedData").resolve("dataDistributionPerZone.csv"); + // aufgrund des separaten Aufbaus der Ordnerstruktur wird der Pfad angepasst +// Path outputFileInOutputFolder = output.resolve("calculatedData").resolve("dataDistributionPerZone.csv"); + Path outputFileInOutputFolder = output.resolve("dataDistributionPerZone.csv"); - landuseCategoriesAndDataConnection.put("Inhabitants", - new ArrayList(Arrays.asList("residential", "apartments", "dormitory", "dwelling_house", "house", - "retirement_home", "semidetached_house", "detached"))); - landuseCategoriesAndDataConnection.put("Employee Primary Sector", new ArrayList( - Arrays.asList("farmyard", "farmland", "farm", "farm_auxiliary", "greenhouse", "agricultural"))); - landuseCategoriesAndDataConnection.put("Employee Construction", - new ArrayList(List.of("construction"))); - landuseCategoriesAndDataConnection.put("Employee Secondary Sector Rest", - new ArrayList(Arrays.asList("industrial", "factory", "manufacture", "bakehouse"))); - landuseCategoriesAndDataConnection.put("Employee Retail", - new ArrayList(Arrays.asList("retail", "kiosk", "mall", "shop", "supermarket"))); - landuseCategoriesAndDataConnection.put("Employee Traffic/Parcels", new ArrayList( - Arrays.asList("commercial", "post_office", "storage", "storage_tank", "warehouse"))); - landuseCategoriesAndDataConnection.put("Employee Tertiary Sector Rest", new ArrayList( - Arrays.asList("commercial", "embassy", "foundation", "government", "office", "townhall"))); - - if (usedLanduseConfiguration.equals("useExistingDataDistribution")) { - - if (!Files.exists(pathToExistingDataDistributionToZones)) { - log.error("Required data per zone file {} not found", pathToExistingDataDistributionToZones); - } + log.info("New analyze for data distribution is started. The used method is: " + usedLanduseConfiguration); + Map> landuseCategoriesPerZone = new HashMap<>(); + createLanduseDistribution(landuseCategoriesPerZone, indexLanduse, indexZones, indexInvestigationAreaRegions, + usedLanduseConfiguration, indexBuildings, landuseCategoriesAndDataConnection, + buildingsPerZone, shapeFileZoneNameColumn, zoneIdRegionConnection); - try (BufferedReader reader = IOUtils.getBufferedReader(pathToExistingDataDistributionToZones.toString())) { - CSVParser parse = CSVFormat.Builder.create(CSVFormat.DEFAULT).setDelimiter('\t').setHeader() - .setSkipHeaderRecord(true).build().parse(reader); + Map> investigationAreaData = new HashMap<>(); + readAreaData(investigationAreaData, pathToInvestigationAreaData); - for (CSVRecord record : parse) { - String zoneID = record.get("zoneID"); - resultingDataPerZone.put(zoneID, new Object2DoubleOpenHashMap<>()); - for (int n = 2; n < parse.getHeaderMap().size(); n++) { - resultingDataPerZone.get(zoneID).mergeDouble(parse.getHeaderNames().get(n), - Double.parseDouble(record.get(n)), Double::sum); - } - } - } - log.info("Data distribution for " + resultingDataPerZone.size() + " zones was imported from " + - pathToExistingDataDistributionToZones); - Files.copy(pathToExistingDataDistributionToZones, outputFileInOutputFolder, StandardCopyOption.COPY_ATTRIBUTES); - } - - else { + createResultingDataForLanduseInZones(landuseCategoriesPerZone, investigationAreaData, resultingDataPerZone, + landuseCategoriesAndDataConnection, zoneIdRegionConnection); - log.info("New analyze for data distribution is started. The used method is: " + usedLanduseConfiguration); + writeResultOfDataDistribution(resultingDataPerZone, outputFileInOutputFolder, + zoneIdRegionConnection); - Map> landuseCategoriesPerZone = new HashMap<>(); - createLanduseDistribution(landuseCategoriesPerZone, indexLanduse, indexZones, indexInvestigationAreaRegions, - usedLanduseConfiguration, indexBuildings, landuseCategoriesAndDataConnection, - buildingsPerZone, shapeFileZoneNameColumn, zoneIdRegionConnection); - - Map> investigationAreaData = new HashMap<>(); - readAreaData(investigationAreaData, pathToInvestigationAreaData); - - createResultingDataForLanduseInZones(landuseCategoriesPerZone, investigationAreaData, resultingDataPerZone, - landuseCategoriesAndDataConnection, zoneIdRegionConnection); - - SmallScaleCommercialTrafficUtils.writeResultOfDataDistribution(resultingDataPerZone, outputFileInOutputFolder, - zoneIdRegionConnection); - } return resultingDataPerZone; } + public static void createDefaultDataConnectionForOSM(Map> landuseCategoriesAndDataConnection) { + landuseCategoriesAndDataConnection.put("Inhabitants", + new ArrayList<>(Arrays.asList("residential", "apartments", "dormitory", "dwelling_house", "house", + "retirement_home", "semidetached_house", "detached"))); + landuseCategoriesAndDataConnection.put("Employee Primary Sector", new ArrayList<>( + Arrays.asList("farmyard", "farmland", "farm", "farm_auxiliary", "greenhouse", "agricultural"))); + landuseCategoriesAndDataConnection.put("Employee Construction", + new ArrayList<>(List.of("construction"))); + landuseCategoriesAndDataConnection.put("Employee Secondary Sector Rest", + new ArrayList<>(Arrays.asList("industrial", "factory", "manufacture", "bakehouse"))); + landuseCategoriesAndDataConnection.put("Employee Retail", + new ArrayList<>(Arrays.asList("retail", "kiosk", "mall", "shop", "supermarket"))); + landuseCategoriesAndDataConnection.put("Employee Traffic/Parcels", new ArrayList<>( + Arrays.asList("commercial", "post_office", "storage", "storage_tank", "warehouse"))); + landuseCategoriesAndDataConnection.put("Employee Tertiary Sector Rest", new ArrayList<>( + Arrays.asList("commercial", "embassy", "foundation", "government", "office", "townhall"))); + } + /** * Creates the resulting data for each zone based on the landuse distribution * and the original data. @@ -169,7 +150,9 @@ private static void createResultingDataForLanduseInZones( } } } - + for (Map.Entry> entry : resultingDataPerZone.entrySet()) { + resultingSumsForZones.put(entry.getKey(), new Object2DoubleOpenHashMap<>(entry.getValue())); + } /* * creates the percentages of each category and zones based on the sum in this * category @@ -257,13 +240,7 @@ private static void createLanduseDistribution(Map buildingsFeatures, if (singleZone != null) { categoriesOfBuilding.forEach(c -> buildingsPerZone .computeIfAbsent(singleZone, k -> new HashMap<>()) - .computeIfAbsent(c, k -> new ArrayList()).add(singleBuildingFeature)); + .computeIfAbsent(c, k -> new ArrayList<>()).add(singleBuildingFeature)); } } log.info("Finished analyzing buildings types."); } + + + /** + * Writes a csv file with the result of the distribution per zone of the input data. + */ + private static void writeResultOfDataDistribution(Map> resultingDataPerZone, + Path outputFileInOutputFolder, Map zoneIdRegionConnection) + throws IOException { + + writeCSVWithCategoryHeader(resultingDataPerZone, outputFileInOutputFolder, zoneIdRegionConnection); + log.info("The data distribution is finished and written to: " + outputFileInOutputFolder); + } + + /** + * Writer of data distribution data. + */ + private static void writeCSVWithCategoryHeader(Map> resultingDataPerZone, + Path outputFileInInputFolder, + Map zoneIdRegionConnection) throws MalformedURLException { + BufferedWriter writer = IOUtils.getBufferedWriter(outputFileInInputFolder.toUri().toURL(), + StandardCharsets.UTF_8, true); + try { + String[] header = new String[]{"zoneID", "region", "Inhabitants", "Employee", "Employee Primary Sector", + "Employee Construction", "Employee Secondary Sector Rest", "Employee Retail", + "Employee Traffic/Parcels", "Employee Tertiary Sector Rest"}; + JOIN.appendTo(writer, header); + writer.write("\n"); + for (String zone : resultingDataPerZone.keySet()) { + List row = new ArrayList<>(); + row.add(zone); + row.add(zoneIdRegionConnection.get(zone)); + for (String category : header) { + if (!category.equals("zoneID") && !category.equals("region")) + row.add(String.valueOf((int) Math.round(resultingDataPerZone.get(zone).getDouble(category)))); + } + JOIN.appendTo(writer, row); + writer.write("\n"); + } + + writer.close(); + + } catch (IOException e) { + log.error("Could not write the csv file with the data distribution data.", e); + } + } + + static double getShareOfTheBuildingAreaOfTheRelatedAreaOfTheZone(String zone, int area, String category){ + return area / resultingSumsForZones.get(zone).getDouble(category); + } } diff --git a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SCTUtils.java b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SCTUtils.java index 843a690196d..87319ceaac0 100644 --- a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SCTUtils.java +++ b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SCTUtils.java @@ -9,22 +9,22 @@ */ public class SCTUtils { - static ShpOptions.Index getZoneIndex(Path inputDataDirectory) { + public static ShpOptions.Index getZoneIndex(Path inputDataDirectory) { Path shapeFileZonePath = inputDataDirectory.resolve("shp/testZones.shp"); return new ShpOptions(shapeFileZonePath, null, null).createIndex("name"); } - static ShpOptions.Index getIndexLanduse(Path inputDataDirectory) { + public static ShpOptions.Index getIndexLanduse(Path inputDataDirectory) { Path shapeFileLandusePath = inputDataDirectory.resolve("shp/testLanduse.shp"); return new ShpOptions(shapeFileLandusePath, null, null).createIndex("fclass"); } - static ShpOptions.Index getIndexBuildings(Path inputDataDirectory) { + public static ShpOptions.Index getIndexBuildings(Path inputDataDirectory) { Path shapeFileBuildingsPath = inputDataDirectory.resolve("shp/testBuildings.shp"); return new ShpOptions(shapeFileBuildingsPath, null, null).createIndex("type"); } - static ShpOptions.Index getIndexRegions(Path inputDataDirectory) { + public static ShpOptions.Index getIndexRegions(Path inputDataDirectory) { Path shapeFileRegionsPath = inputDataDirectory.resolve("shp/testRegions.shp"); return new ShpOptions(shapeFileRegionsPath, null, null).createIndex("region"); } diff --git a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java index 5aa06d111fc..3a564be62a8 100644 --- a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java +++ b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/SmallScaleCommercialTrafficUtilsTest.java @@ -28,8 +28,8 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.facilities.ActivityFacility; import org.matsim.testcases.MatsimTestUtils; -import org.opengis.feature.simple.SimpleFeature; import java.io.IOException; import java.net.URISyntaxException; @@ -58,13 +58,12 @@ void findZoneOfLinksTest() throws IOException, URISyntaxException { config.network().setInputFile(networkPath); config.network().setInputCRS("EPSG:4326"); Scenario scenario = ScenarioUtils.loadScenario(config); - Map>> buildingsPerZone = new HashMap<>(); + Map>> facilitiesPerZone = new HashMap<>(); String shapeFileZoneNameColumn = "name"; - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem(), - shapeFileZoneNameColumn), - buildingsPerZone); + Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand.filterLinksForZones(scenario, + SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem(), shapeFileZoneNameColumn), + facilitiesPerZone); Assertions.assertEquals(3, regionLinksMap.size(), MatsimTestUtils.EPSILON); Assertions.assertEquals(60, regionLinksMap.get("area1").size(), MatsimTestUtils.EPSILON); diff --git a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java index b680e568ffb..a11a5df9bd4 100644 --- a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java +++ b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGenerationTest.java @@ -29,10 +29,12 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.facilities.ActivityFacility; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; import org.matsim.freight.carriers.CarriersUtils; import org.matsim.smallScaleCommercialTrafficGeneration.TrafficVolumeGeneration.TrafficVolumeKey; +import org.matsim.smallScaleCommercialTrafficGeneration.prepare.LanduseBuildingAnalysis; import org.matsim.testcases.MatsimTestUtils; import org.opengis.feature.simple.SimpleFeature; @@ -41,6 +43,8 @@ import java.nio.file.Path; import java.util.*; +import static org.matsim.smallScaleCommercialTrafficGeneration.prepare.LanduseBuildingAnalysis.createDefaultDataConnectionForOSM; + /** * @author Ricardo Ewert * @@ -59,16 +63,16 @@ void testTrafficVolumeGenerationCommercialPersonTraffic() throws IOException { Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); - String usedLanduseConfiguration = "useExistingDataDistribution"; + String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String shapeFileZoneNameColumn = "name"; Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); - Path pathToExistingDataDistributionToZones = Path.of(utils.getPackageInputDirectory()).resolve("dataDistributionPerZone.csv"); + createDefaultDataConnectionForOSM(landuseCategoriesAndDataConnection); Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, SCTUtils.getIndexLanduse(inputDataDirectory), SCTUtils.getZoneIndex(inputDataDirectory), SCTUtils.getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, pathToExistingDataDistributionToZones); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); String usedTrafficType = "commercialPersonTraffic"; @@ -189,16 +193,16 @@ void testTrafficVolumeGenerationGoodsTraffic() throws IOException { Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); - String usedLanduseConfiguration = "useExistingDataDistribution"; + String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String shapeFileZoneNameColumn = "name"; Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); - Path pathToExistingDataDistributionToZones = Path.of(utils.getPackageInputDirectory()).resolve("dataDistributionPerZone.csv"); + createDefaultDataConnectionForOSM(landuseCategoriesAndDataConnection); Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, SCTUtils.getIndexLanduse(inputDataDirectory), SCTUtils.getZoneIndex(inputDataDirectory), SCTUtils.getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, pathToExistingDataDistributionToZones); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); String usedTrafficType = "goodsTraffic"; double sample = 1.; @@ -395,15 +399,14 @@ void testAddingExistingScenarios() throws Exception { config.network().setInputCRS("EPSG:4326"); config.setContext(inputDataDirectory.resolve("config.xml").toUri().toURL()); Scenario scenario = ScenarioUtils.loadScenario(config); - Map>> buildingsPerZone = new HashMap<>(); + Map>> facilitiesPerZone = new HashMap<>(); String shapeFileZoneNameColumn = "name"; - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem(), - shapeFileZoneNameColumn), - buildingsPerZone); + Map, Link>> linksPerZone = GenerateSmallScaleCommercialTrafficDemand.filterLinksForZones(scenario, + SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem(), shapeFileZoneNameColumn), + facilitiesPerZone); - SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); + SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, linksPerZone); Assertions.assertEquals(3, CarriersUtils.getCarriers(scenario).getCarriers().size(), MatsimTestUtils.EPSILON); Assertions.assertEquals(1, CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().size(), MatsimTestUtils.EPSILON); @@ -465,13 +468,13 @@ void testAddingExistingScenariosWithSample() throws Exception { config.network().setInputCRS("EPSG:4326"); config.setContext(inputDataDirectory.resolve("config.xml").toUri().toURL()); Scenario scenario = ScenarioUtils.loadScenario(config); - Map>> buildingsPerZone = new HashMap<>(); - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand + Map>> facilitiesPerZone = new HashMap<>(); + Map, Link>> linksPerZone = GenerateSmallScaleCommercialTrafficDemand .filterLinksForZones(scenario, SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, config.global().getCoordinateSystem(), shapeFileZoneNameColumn), - buildingsPerZone); + facilitiesPerZone); - SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); + SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, linksPerZone); Assertions.assertEquals(2, CarriersUtils.getCarriers(scenario).getCarriers().size(), MatsimTestUtils.EPSILON); Assertions.assertEquals(1, CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().size(), MatsimTestUtils.EPSILON); @@ -511,13 +514,13 @@ void testReducingDemandAfterAddingExistingScenarios_goods() throws Exception { Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); - String usedLanduseConfiguration = "useExistingDataDistribution"; + String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String networkPath = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; String usedTrafficType = "goodsTraffic"; double sample = 1.; String shapeFileZoneNameColumn = "name"; Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); - Path pathToExistingDataDistributionToZones = Path.of(utils.getPackageInputDirectory()).resolve("dataDistributionPerZone.csv"); + createDefaultDataConnectionForOSM(landuseCategoriesAndDataConnection); ArrayList modesORvehTypes = new ArrayList<>( Arrays.asList("vehTyp1", "vehTyp2", "vehTyp3", "vehTyp4", "vehTyp5")); @@ -528,24 +531,25 @@ void testReducingDemandAfterAddingExistingScenarios_goods() throws Exception { config.setContext(inputDataDirectory.resolve("config.xml").toUri().toURL()); Scenario scenario = ScenarioUtils.loadScenario(config); TrafficVolumeGeneration.setInputParameters(usedTrafficType); + Map>> facilitiesPerZone = new HashMap<>(); Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, SCTUtils.getIndexLanduse(inputDataDirectory), SCTUtils.getZoneIndex(inputDataDirectory), SCTUtils.getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, pathToExistingDataDistributionToZones); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); Map> trafficVolumePerTypeAndZone_stop = TrafficVolumeGeneration .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); - Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, SCTUtils.getZoneIndex(inputDataDirectory), buildingsPerZone); + Map, Link>> linksPerZone = GenerateSmallScaleCommercialTrafficDemand + .filterLinksForZones(scenario, SCTUtils.getZoneIndex(inputDataDirectory), facilitiesPerZone); - SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); + SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, linksPerZone); - TrafficVolumeGeneration.reduceDemandBasedOnExistingCarriers(scenario, regionLinksMap, usedTrafficType, + TrafficVolumeGeneration.reduceDemandBasedOnExistingCarriers(scenario, linksPerZone, usedTrafficType, trafficVolumePerTypeAndZone_start, trafficVolumePerTypeAndZone_stop); // test for "area1" @@ -667,17 +671,17 @@ void testReducingDemandAfterAddingExistingScenarios_goods() throws Exception { void testReducingDemandAfterAddingExistingScenarios_commercialPersonTraffic() throws Exception { Map> landuseCategoriesAndDataConnection = new HashMap<>(); Map>> buildingsPerZone = new HashMap<>(); + Map>> facilitiesPerZone = new HashMap<>(); Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); - String usedLanduseConfiguration = "useExistingDataDistribution"; + String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String networkPath = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; String usedTrafficType = "commercialPersonTraffic"; double sample = 1.; String shapeFileZoneNameColumn = "name"; Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); - Path pathToExistingDataDistributionToZones = Path.of(utils.getPackageInputDirectory()).resolve("dataDistributionPerZone.csv"); ArrayList modesORvehTypes = new ArrayList<>( List.of("total")); @@ -689,11 +693,12 @@ void testReducingDemandAfterAddingExistingScenarios_commercialPersonTraffic() th Scenario scenario = ScenarioUtils.loadScenario(config); TrafficVolumeGeneration.setInputParameters(usedTrafficType); + createDefaultDataConnectionForOSM(landuseCategoriesAndDataConnection); Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, SCTUtils.getIndexLanduse(inputDataDirectory), SCTUtils.getZoneIndex(inputDataDirectory), SCTUtils.getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, pathToExistingDataDistributionToZones); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); Map> trafficVolumePerTypeAndZone_start = TrafficVolumeGeneration .createTrafficVolume_start(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); @@ -701,7 +706,7 @@ void testReducingDemandAfterAddingExistingScenarios_commercialPersonTraffic() th .createTrafficVolume_stop(resultingDataPerZone, output, sample, modesORvehTypes, usedTrafficType); Map, Link>> regionLinksMap = GenerateSmallScaleCommercialTrafficDemand - .filterLinksForZones(scenario, SCTUtils.getZoneIndex(inputDataDirectory), buildingsPerZone); + .filterLinksForZones(scenario, SCTUtils.getZoneIndex(inputDataDirectory), facilitiesPerZone); SmallScaleCommercialTrafficUtils.readExistingModels(scenario, sample, regionLinksMap); diff --git a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java index 7190ba7350d..dd98d5e9ef7 100644 --- a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java +++ b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/TripDistributionMatrixTest.java @@ -28,6 +28,7 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.core.network.NetworkUtils; import org.matsim.smallScaleCommercialTrafficGeneration.TrafficVolumeGeneration.TrafficVolumeKey; +import org.matsim.smallScaleCommercialTrafficGeneration.prepare.LanduseBuildingAnalysis; import org.matsim.testcases.MatsimTestUtils; import org.opengis.feature.simple.SimpleFeature; @@ -56,18 +57,17 @@ void testTripDistributionCommercialPersonTrafficTraffic() throws IOException { Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); - String usedLanduseConfiguration = "useExistingDataDistribution"; + String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String networkLocation = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; Network network = NetworkUtils.readNetwork(networkLocation); String shapeFileZoneNameColumn = "name"; Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); - Path pathToExistingDataDistributionToZones = Path.of(utils.getPackageInputDirectory()).resolve("dataDistributionPerZone.csv"); Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, pathToExistingDataDistributionToZones); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); String usedTrafficType = "commercialPersonTraffic"; double sample = 1.; @@ -148,17 +148,17 @@ void testTripDistributionGoodsTraffic() throws IOException { Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); - String usedLanduseConfiguration = "useExistingDataDistribution"; + String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String networkLocation = "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"; Network network = NetworkUtils.readNetwork(networkLocation); String shapeFileZoneNameColumn = "name"; Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); - Path pathToExistingDataDistributionToZones = Path.of(utils.getPackageInputDirectory()).resolve("dataDistributionPerZone.csv"); + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, getIndexLanduse(inputDataDirectory), getZoneIndex(inputDataDirectory), getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, pathToExistingDataDistributionToZones); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); String usedTrafficType = "goodsTraffic"; double sample = 1.; diff --git a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/CreateDataDistributionOfStructureDataTest.java b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/CreateDataDistributionOfStructureDataTest.java new file mode 100644 index 00000000000..f7c499a5add --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/CreateDataDistributionOfStructureDataTest.java @@ -0,0 +1,50 @@ +package org.matsim.smallScaleCommercialTrafficGeneration.prepare; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.testcases.MatsimTestUtils; + +import java.nio.file.Path; + +class CreateDataDistributionOfStructureDataTest { + @RegisterExtension + private MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void testDataDistributionOfStructureData() { + String useOSMBuildingsAndLanduse = "useOSMBuildingsAndLanduse"; + String regionsShapeFileName = Path.of(utils.getPackageInputDirectory()).getParent().resolve("shp/testRegions.shp").toString(); + String regionsShapeRegionColumn = "region"; + String zoneShapeFileName = Path.of(utils.getPackageInputDirectory()).getParent().resolve("shp/testZones.shp").toString(); + String zoneShapeFileNameColumn = "name"; + String buildingsShapeFileName = Path.of(utils.getPackageInputDirectory()).getParent().resolve("shp/testBuildings.shp").toString(); + String shapeFileBuildingTypeColumn = "type"; + String landuseShapeFileName = Path.of(utils.getPackageInputDirectory()).getParent().resolve("shp/testLanduse.shp").toString(); + String shapeFileLanduseTypeColumn = "fclass"; + String shapeCRS = "EPSG:4326"; + String investigationAreaData = Path.of(utils.getPackageInputDirectory()).getParent().resolve("investigationAreaData.csv").toString(); + + new CreateDataDistributionOfStructureData().execute( + "--pathOutput", utils.getOutputDirectory(), + "--landuseConfiguration", useOSMBuildingsAndLanduse, + "--regionsShapeFileName", regionsShapeFileName, + "--regionsShapeRegionColumn", regionsShapeRegionColumn, + "--zoneShapeFileName", zoneShapeFileName, + "--zoneShapeFileNameColumn", zoneShapeFileNameColumn, + "--buildingsShapeFileName", buildingsShapeFileName, + "--shapeFileBuildingTypeColumn", shapeFileBuildingTypeColumn, + "--landuseShapeFileName", landuseShapeFileName, + "--shapeFileLanduseTypeColumn", shapeFileLanduseTypeColumn, + "--shapeCRS", shapeCRS, + "--pathToInvestigationAreaData", investigationAreaData); + + Assertions.assertTrue(Path.of(utils.getOutputDirectory()).resolve("dataDistributionPerZone.csv").toFile().exists()); + Assertions.assertTrue(Path.of(utils.getOutputDirectory()).resolve("dataDistributionPerZone.csv").toFile().length() > 0); + + Assertions.assertTrue(Path.of(utils.getOutputDirectory()).resolve("commercialFacilities.xml.gz").toFile().exists()); + Assertions.assertTrue(Path.of(utils.getOutputDirectory()).resolve("commercialFacilities.xml.gz").toFile().length() > 0); + + //TODO add tests for the created facilities + } +} diff --git a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysisTest.java b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/LanduseBuildingAnalysisTest.java similarity index 92% rename from contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysisTest.java rename to contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/LanduseBuildingAnalysisTest.java index fa640744c92..a65d97b0686 100644 --- a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/LanduseBuildingAnalysisTest.java +++ b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/prepare/LanduseBuildingAnalysisTest.java @@ -17,12 +17,13 @@ * See also COPYING, LICENSE and WARRANTY file * * * * *********************************************************************** */ -package org.matsim.smallScaleCommercialTrafficGeneration; +package org.matsim.smallScaleCommercialTrafficGeneration.prepare; import it.unimi.dsi.fastutil.objects.Object2DoubleMap; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.smallScaleCommercialTrafficGeneration.SCTUtils; import org.matsim.testcases.MatsimTestUtils; import org.opengis.feature.simple.SimpleFeature; @@ -33,6 +34,8 @@ import java.util.List; import java.util.Map; +import static org.matsim.smallScaleCommercialTrafficGeneration.prepare.LanduseBuildingAnalysis.createDefaultDataConnectionForOSM; + /** * @author Ricardo Ewert * @@ -49,18 +52,19 @@ void testReadOfDataDistributionPerZoneAndBuildingAnalysis() throws IOException { Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); - Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); - String usedLanduseConfiguration = "useExistingDataDistribution"; + Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()).getParent(); + String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String shapeFileZoneNameColumn = "name"; - Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); - Path pathToExistingDataDistributionToZones = Path.of(utils.getPackageInputDirectory()).resolve("dataDistributionPerZone.csv"); + Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).getParent().resolve("investigationAreaData.csv"); // Test if the reading of the existing data distribution works correctly + createDefaultDataConnectionForOSM(landuseCategoriesAndDataConnection); + Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, SCTUtils.getIndexLanduse(inputDataDirectory), SCTUtils.getZoneIndex(inputDataDirectory), SCTUtils.getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, pathToExistingDataDistributionToZones); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); Assertions.assertEquals(3, resultingDataPerZone.size(), MatsimTestUtils.EPSILON); @@ -153,8 +157,6 @@ void testReadOfDataDistributionPerZoneAndBuildingAnalysis() throws IOException { // tests if the reading of the buildings works correctly List buildingsFeatures = SCTUtils.getIndexBuildings(inputDataDirectory).getAllFeatures(); Assertions.assertEquals(31, buildingsFeatures.size(), MatsimTestUtils.EPSILON); - LanduseBuildingAnalysis.analyzeBuildingType(buildingsFeatures, buildingsPerZone, - landuseCategoriesAndDataConnection, SCTUtils.getIndexLanduse(inputDataDirectory), SCTUtils.getZoneIndex(inputDataDirectory)); Assertions.assertEquals(3, buildingsPerZone.size(), MatsimTestUtils.EPSILON); Assertions.assertTrue(buildingsPerZone.containsKey("area1")); @@ -162,9 +164,9 @@ void testReadOfDataDistributionPerZoneAndBuildingAnalysis() throws IOException { Assertions.assertTrue(buildingsPerZone.containsKey("area3")); // test for area1 - Map> builingsPerArea1 = buildingsPerZone.get("area1"); - Assertions.assertEquals(7, builingsPerArea1.size(), MatsimTestUtils.EPSILON); - List inhabitantsBuildings = builingsPerArea1.get("Inhabitants"); + Map> buildingsPerArea1 = buildingsPerZone.get("area1"); + Assertions.assertEquals(7, buildingsPerArea1.size(), MatsimTestUtils.EPSILON); + List inhabitantsBuildings = buildingsPerArea1.get("Inhabitants"); Assertions.assertEquals(4, inhabitantsBuildings.size(), MatsimTestUtils.EPSILON); for (SimpleFeature singleBuilding : inhabitantsBuildings) { int id = (int) (long) singleBuilding.getAttribute("osm_id"); @@ -183,13 +185,13 @@ void testReadOfDataDistributionPerZoneAndBuildingAnalysis() throws IOException { } else Assertions.fail(); } - Assertions.assertFalse(builingsPerArea1.containsKey("Employee Primary Sector")); - Assertions.assertEquals(1, builingsPerArea1.get("Employee Construction").size(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(1, builingsPerArea1.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(2, builingsPerArea1.get("Employee Retail").size(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(1, builingsPerArea1.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(2, builingsPerArea1.get("Employee Tertiary Sector Rest").size(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(6, builingsPerArea1.get("Employee").size(), MatsimTestUtils.EPSILON); + Assertions.assertFalse(buildingsPerArea1.containsKey("Employee Primary Sector")); + Assertions.assertEquals(1, buildingsPerArea1.get("Employee Construction").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, buildingsPerArea1.get("Employee Secondary Sector Rest").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, buildingsPerArea1.get("Employee Retail").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1, buildingsPerArea1.get("Employee Traffic/Parcels").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2, buildingsPerArea1.get("Employee Tertiary Sector Rest").size(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6, buildingsPerArea1.get("Employee").size(), MatsimTestUtils.EPSILON); // test for area2 Map> builingsPerArea2 = buildingsPerZone.get("area2"); @@ -244,16 +246,18 @@ void testLanduseDistribution() throws IOException { Path output = Path.of(utils.getOutputDirectory()); assert(new File(output.resolve("calculatedData").toString()).mkdir()); - Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()); + Path inputDataDirectory = Path.of(utils.getPackageInputDirectory()).getParent(); String usedLanduseConfiguration = "useOSMBuildingsAndLanduse"; String shapeFileZoneNameColumn = "name"; - Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).resolve("investigationAreaData.csv"); + Path pathToInvestigationAreaData = Path.of(utils.getPackageInputDirectory()).getParent().resolve("investigationAreaData.csv"); + createDefaultDataConnectionForOSM(landuseCategoriesAndDataConnection); + // Analyze resultingData per zone Map> resultingDataPerZone = LanduseBuildingAnalysis .createInputDataDistribution(output, landuseCategoriesAndDataConnection, usedLanduseConfiguration, SCTUtils.getIndexLanduse(inputDataDirectory), SCTUtils.getZoneIndex(inputDataDirectory), SCTUtils.getIndexBuildings(inputDataDirectory), - SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData, null); + SCTUtils.getIndexRegions(inputDataDirectory), shapeFileZoneNameColumn, buildingsPerZone, pathToInvestigationAreaData); Assertions.assertEquals(3, resultingDataPerZone.size(), MatsimTestUtils.EPSILON); diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/commercialFacilities.xml.gz b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/commercialFacilities.xml.gz new file mode 100644 index 00000000000..1c611cba984 Binary files /dev/null and b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/commercialFacilities.xml.gz differ diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz index cedefa5d9a5..8d77e5ca6b6 100644 Binary files a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz and b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz differ