Skip to content

Commit

Permalink
Merge pull request #29 from matsim-vsp/street-durations
Browse files Browse the repository at this point in the history
add durations for street
  • Loading branch information
paulheinr authored Jun 7, 2024
2 parents 205bd3f + 662bf84 commit 7751d56
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 113 deletions.
6 changes: 2 additions & 4 deletions src/main/java/org/tub/vsp/bvwp/RunCsvWriting.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@
import org.tub.vsp.bvwp.scraping.StreetScraper;

import java.util.List;
import java.util.Map;

public class RunCsvWriting {
public static void main(String[] args) {
String filePath = "../../shared-svn/";
Map<String, Double> constructionCostsByProject = BvwpUtils.getConstructionCostsFromTudFile(filePath );
// Map<String, Double> constructionCostsByProject = BvwpUtils.getConstructionCostsFromTudFile(filePath );

List<StreetAnalysisDataContainer> allStreetBaseData =
new StreetScraper().extractAllLocalBaseData("./data/street/all", "A", ".*", "")
.stream()
.map(s -> new StreetAnalysisDataContainer(s,
constructionCostsByProject.get(s.getProjectInformation().getProjectNumber())))
.map(s -> new StreetAnalysisDataContainer(s, 0))
.toList();

StreetCsvWriter csvWriter = new StreetCsvWriter("output/street_data.csv");
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/tub/vsp/bvwp/data/Headers.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ public final class Headers{
public static final String NKV_ELTTIME_CARBON700TPR0_INVCOSTTUD = "NKV_elTtime_carbon700tpr0_invcostTud";
public static final String NKV_ELTTIME_CARBON2000_INVCOSTTUD = "NKV_elTtime_carbon2000_invcostTud";

public static final String DAUER_PLANUNG = "Planungsdauer_jahre";
public static final String DAUER_BAU = "Baudauer_jahre";
public static final String DAUER_BETRIEB = "Betriebsdauer_jahre";

public static String capped5Of( String str ) {
int cap=5;
return cappedOf( cap, str );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.apache.logging.log4j.Logger;
import org.tub.vsp.bvwp.data.type.Benefit;
import org.tub.vsp.bvwp.data.type.Cost;
import org.tub.vsp.bvwp.data.type.Durations;
import org.tub.vsp.bvwp.data.type.Emission;

import java.util.Map;
Expand All @@ -30,6 +31,8 @@ public class StreetCostBenefitAnalysisDataContainer {
private Benefit overallBenefit;
private Cost cost;

private Durations durations;

public Benefit getNb() {
return nb;
}
Expand Down Expand Up @@ -115,6 +118,11 @@ public Map<Emission, Benefit> getNa() {
return na;
}

public StreetCostBenefitAnalysisDataContainer setNa(Map<Emission, Benefit> na) {
this.na = na;
return this;
}

public Benefit getNaCumulated() {
if (na == null) {
return new Benefit();
Expand All @@ -125,11 +133,6 @@ public Benefit getNaCumulated() {
.reduce(new Benefit(0., 0.), Benefit::add);
}

public StreetCostBenefitAnalysisDataContainer setNa(Map<Emission, Benefit> na) {
this.na = na;
return this;
}

public Benefit getNt() {
return nt;
}
Expand Down Expand Up @@ -192,68 +195,13 @@ public Benefit getCo2EquivalentBenefit() {
return emissions.add(lifecycle);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

StreetCostBenefitAnalysisDataContainer that = (StreetCostBenefitAnalysisDataContainer) o;

if (!Objects.equals(nb, that.nb)) {
return false;
}
if (!Objects.equals(nw, that.nw)) {
return false;
}
if (!Objects.equals(ns, that.ns)) {
return false;
}
if (!Objects.equals(nrz, that.nrz)) {
return false;
}
if (!Objects.equals(ntz, that.ntz)) {
return false;
}
if (!Objects.equals(ni, that.ni)) {
return false;
}
if (!Objects.equals(nl, that.nl)) {
return false;
}
if (!Objects.equals(ng, that.ng)) {
return false;
}
if (!Objects.equals(na, that.na)) {
return false;
}
if (!Objects.equals(nt, that.nt)) {
return false;
}
if (!Objects.equals(nz, that.nz)) {
return false;
}
return Objects.equals(cost, that.cost);
public Durations getDurations() {
return durations;
}

@Override
public int hashCode() {
int result = nb != null ? nb.hashCode() : 0;
result = 31 * result + (nw != null ? nw.hashCode() : 0);
result = 31 * result + (ns != null ? ns.hashCode() : 0);
result = 31 * result + (nrz != null ? nrz.hashCode() : 0);
result = 31 * result + (ntz != null ? ntz.hashCode() : 0);
result = 31 * result + (ni != null ? ni.hashCode() : 0);
result = 31 * result + (nl != null ? nl.hashCode() : 0);
result = 31 * result + (ng != null ? ng.hashCode() : 0);
result = 31 * result + (na != null ? na.hashCode() : 0);
result = 31 * result + (nt != null ? nt.hashCode() : 0);
result = 31 * result + (nz != null ? nz.hashCode() : 0);
result = 31 * result + (cost != null ? cost.hashCode() : 0);
return result;
public StreetCostBenefitAnalysisDataContainer setDurations(Durations durations) {
this.durations = durations;
return this;
}

public Benefit getNbPersonnel() {
Expand All @@ -273,4 +221,39 @@ public StreetCostBenefitAnalysisDataContainer setNbVehicle(Benefit nbVehicle) {
this.nbVehicle = nbVehicle;
return this;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

StreetCostBenefitAnalysisDataContainer that = (StreetCostBenefitAnalysisDataContainer) o;
return Objects.equals(nb, that.nb) && Objects.equals(nbOperations, that.nbOperations) && Objects.equals(nbPersonnel, that.nbPersonnel) && Objects.equals(nbVehicle, that.nbVehicle) && Objects.equals(nw, that.nw) && Objects.equals(ns, that.ns) && Objects.equals(nrz, that.nrz) && Objects.equals(ntz, that.ntz) && Objects.equals(ni, that.ni) && Objects.equals(nl, that.nl) && Objects.equals(ng, that.ng) && Objects.equals(na, that.na) && Objects.equals(nt, that.nt) && Objects.equals(nz, that.nz) && Objects.equals(overallBenefit, that.overallBenefit) && Objects.equals(cost, that.cost) && Objects.equals(durations, that.durations);
}

@Override
public int hashCode() {
int result = Objects.hashCode(nb);
result = 31 * result + Objects.hashCode(nbOperations);
result = 31 * result + Objects.hashCode(nbPersonnel);
result = 31 * result + Objects.hashCode(nbVehicle);
result = 31 * result + Objects.hashCode(nw);
result = 31 * result + Objects.hashCode(ns);
result = 31 * result + Objects.hashCode(nrz);
result = 31 * result + Objects.hashCode(ntz);
result = 31 * result + Objects.hashCode(ni);
result = 31 * result + Objects.hashCode(nl);
result = 31 * result + Objects.hashCode(ng);
result = 31 * result + Objects.hashCode(na);
result = 31 * result + Objects.hashCode(nt);
result = 31 * result + Objects.hashCode(nz);
result = 31 * result + Objects.hashCode(overallBenefit);
result = 31 * result + Objects.hashCode(cost);
result = 31 * result + Objects.hashCode(durations);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.tub.vsp.bvwp.JSoupUtils;
import org.tub.vsp.bvwp.data.type.Benefit;
import org.tub.vsp.bvwp.data.type.Cost;
import org.tub.vsp.bvwp.data.type.Durations;

import java.text.ParseException;
import java.util.Optional;
Expand Down Expand Up @@ -43,4 +44,25 @@ public static Cost extractCosts(Element table) {

return new Cost(costs, overallCosts);
}

public static Durations extractDurations(Element table) {
double planning;
double construction;
double maintenance;
try {
planning = parseNumberWithSuffix(JSoupUtils.getTextFromRowAndCol(table, 1, 1), "Monate") / 12.;
construction = parseNumberWithSuffix(JSoupUtils.getTextFromRowAndCol(table, 2, 1), "Monate") / 12.;
maintenance = parseNumberWithSuffix(JSoupUtils.getTextFromRowAndCol(table, 3, 1), "Jahre");
} catch (ParseException e) {
logger.warn("Could not parse duration value from {}", table);
return null;
}

return new Durations(planning, construction, maintenance);
}

private static Double parseNumberWithSuffix(String content, String suffix) throws ParseException {
assert content.endsWith(suffix);
return JSoupUtils.parseDouble(content.split(" ")[0]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ public static StreetCostBenefitAnalysisDataContainer mapDocument(Document docume
StreetCostBenefitMapper::isBenefitTable);
Optional<Element> costTable = JSoupUtils.getTableByCssKeyAndPredicate(document, "table.table_kosten",
StreetCostBenefitMapper::isCostTable);
Optional<Element> durationsTable = JSoupUtils.getTableByCssKeyAndPredicate(document, "table.table_kosten2",
StreetCostBenefitMapper::isDurationsTable);

//We only scrape the cumulated values
benefit.ifPresent(element -> result.setNb(extractSimpleBenefit(element, "NB"))
.setNbVehicle(extractSimpleBenefit(element, "Fahrzeugvorhaltekosten", 0))
.setNbPersonnel(extractSimpleBenefit(element, "Betriebsführungskosten " +
"(Personal)", 0))
.setNbOperations(extractSimpleBenefit(element, "Betriebsführungskosten " +
"(Betrieb)", 0))
.setNbPersonnel(extractSimpleBenefit(element, "Betriebsführungskosten (Personal)", 0))
.setNbOperations(extractSimpleBenefit(element, "Betriebsführungskosten (Betrieb)", 0))
.setNw(extractSimpleBenefit(element, "NW"))
.setNs(extractSimpleBenefit(element, "NS"))
.setNrz(extractSimpleBenefit(element, "NRZ"))
Expand All @@ -46,6 +46,8 @@ public static StreetCostBenefitAnalysisDataContainer mapDocument(Document docume

costTable.ifPresent(element -> result.setCost(CostBenefitMapperUtils.extractCosts(element)));

durationsTable.ifPresent(element -> result.setDurations(CostBenefitMapperUtils.extractDurations(element)));

return result;
}

Expand All @@ -69,6 +71,13 @@ private static boolean isCostTable(Element element) {
.contains("Summe bewertungsrelevanter Investitionskosten");
}

private static boolean isDurationsTable(Element element) {
return element.select("tr")
.get(0)
.text()
.contains("Grundlagen der Barwertermittlung");
}

private static Benefit extractSimpleBenefit(Element table, String key) {
return extractSimpleBenefit(table, key, 1);
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/tub/vsp/bvwp/data/type/Durations.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.tub.vsp.bvwp.data.type;

public record Durations(double planning, double construction, double operation) {
}
8 changes: 8 additions & 0 deletions src/main/java/org/tub/vsp/bvwp/io/StreetCsvWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ private static List<Object> getCsvRecord(StreetAnalysisDataContainer analysisDat

record.add(Headers.LENGTH, baseDataContainer.getProjectInformation().getLength());

record.add(Headers.DAUER_PLANUNG, baseDataContainer.getCostBenefitAnalysis().getDurations().planning());
record.add(Headers.DAUER_BAU, baseDataContainer.getCostBenefitAnalysis().getDurations().construction());
record.add(Headers.DAUER_BETRIEB, baseDataContainer.getCostBenefitAnalysis().getDurations().operation());

record.add(Headers.ADDTL_PKWKM_ORIG, baseDataContainer.getPhysicalEffect().getVehicleKilometers().overall());
record.add(Headers.ADDTL_PKWKM_INDUZ_ORIG, Optional.ofNullable(baseDataContainer.getPhysicalEffect().getVehicleKilometers().induced() ).orElse(0. ) );

Expand Down Expand Up @@ -246,6 +250,10 @@ private static List<String> getHeaders(List<StreetAnalysisDataContainer> analysi
headers.addStringColumn(Headers.BAUTYP);
headers.addDoubleColumn(Headers.LENGTH);

headers.addDoubleColumn(Headers.DAUER_PLANUNG);
headers.addDoubleColumn(Headers.DAUER_BAU);
headers.addDoubleColumn(Headers.DAUER_BETRIEB);

headers.addDoubleColumn( Headers.ADDTL_PKWKM_ORIG );
headers.addDoubleColumn(Headers.ADDTL_PKWKM_INDUZ_ORIG );
// headers.addDoubleColumn( Headers.PKWKM_INDUZ_NEU ); // added by automagic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@
import org.tub.vsp.bvwp.data.container.base.street.StreetCostBenefitAnalysisDataContainer;
import org.tub.vsp.bvwp.data.type.Benefit;
import org.tub.vsp.bvwp.data.type.Cost;
import org.tub.vsp.bvwp.data.type.Durations;
import org.tub.vsp.bvwp.data.type.Emission;

import java.io.IOException;

class StreetCostBenefitMapperTest {
@Test
void testMapper() throws IOException {
StreetCostBenefitMapper costBenefitMapper = new StreetCostBenefitMapper();
StreetCostBenefitAnalysisDataContainer result =
costBenefitMapper.mapDocument(LocalFileAccessor.getLocalDocument("a20.html"));
StreetCostBenefitAnalysisDataContainer result = StreetCostBenefitMapper.mapDocument(LocalFileAccessor.getLocalDocument("a20.html"));

Assertions.assertEquals(new Benefit(40.55, 1005.26), result.getNb());
Assertions.assertEquals(new Benefit(-31.675, -785.233), result.getNbOperations());
Expand All @@ -29,13 +28,13 @@ void testMapper() throws IOException {
Assertions.assertEquals(new Benefit(0.136, 3.363), result.getNt());
Assertions.assertEquals(new Benefit(29.997, 743.646), result.getNz());
Assertions.assertEquals(new Cost(3145.75, 2737.176), result.getCost());

Assertions.assertEquals(new Durations(120. / 12., 48. / 12., 42.), result.getDurations());
}

@Test
void testNulls() throws IOException {
StreetCostBenefitMapper costBenefitMapper = new StreetCostBenefitMapper();
StreetCostBenefitAnalysisDataContainer result =
costBenefitMapper.mapDocument(LocalFileAccessor.getLocalDocument("a2.html"));
StreetCostBenefitAnalysisDataContainer result = StreetCostBenefitMapper.mapDocument(LocalFileAccessor.getLocalDocument("a2.html"));

Assertions.assertNotNull(result.getNa());
Assertions.assertEquals(result.getNa().get(Emission.CO2), new Benefit(0.0, 0.0));
Expand All @@ -44,5 +43,7 @@ void testNulls() throws IOException {
Assertions.assertEquals(result.getNa().get(Emission.HC), new Benefit(0.0, 0.0));
Assertions.assertEquals(result.getNa().get(Emission.SO2), new Benefit(0.0, 0.0));
Assertions.assertEquals(result.getNa().get(Emission.PM), new Benefit(0.0, 0.0));

Assertions.assertEquals(new Durations(90. / 12., 56. / 12., 31.), result.getDurations());
}
}
4 changes: 2 additions & 2 deletions src/test/java/org/tub/vsp/bvwp/io/JsonIoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ void testSerializeJson_street() throws IOException {
@Test
void testSerializeJson_rail() throws IOException {
RailScraper railScraper = new RailScraper();
RailBaseDataContainer streetBaseData = railScraper.extractBaseData(LocalFileAccessor.getLocalDocument("2-003-v01.html"))
RailBaseDataContainer railBaseData = railScraper.extractBaseData(LocalFileAccessor.getLocalDocument("2-003-v01.html"))
.orElseThrow();

//write Json to file
JsonIo jsonIo = new JsonIo();
String filePath = "src/test/resources/testData/referenceData/2-003-v01.json";
RailBaseDataContainer deserializedContainer = jsonIo.readJson(filePath, RailBaseDataContainer.class);
Assertions.assertEquals(streetBaseData, deserializedContainer);
Assertions.assertEquals(railBaseData, deserializedContainer);
}
}
8 changes: 4 additions & 4 deletions src/test/resources/testData/referenceData/2-003-v01.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
"projectInformation": {
"projectNumber": "2-003-v01",
"title": "ABS/NBS Hamburg / Bremerhaven – Hannover (Y-Trasse)",
"priority": "UNDEFINED",
"priority": "KB",
"bautyp": null,
"length": 200.2
},
"physicalEffect": {
"emissionsDataContainer": {
"emissions": {
"CO2": -74699.0,
"HC": 6.0,
"SO2": -9.0,
"NOX": -65.0,
"HC": 6.0,
"CO": -69.0,
"PM": -1.0,
"CO": -69.0
"CO2": -74699.0
}
}
},
Expand Down
4 changes: 2 additions & 2 deletions src/test/resources/testData/referenceData/a20.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
project _name;URL;Einstufung;bautyp;length;addtl_pkwkm_orig;addtl_pkwkm_induz;b_fzkm_orig;co2_equivalents_emissions_orig;b_co2_equivalents_orig;b_overall_orig;investmentCost_orig;DTV_Planfall;addtl_lane_km;b_orig_per_km;NKV_orig;NKV_co2;BCR_co2_680;NKV_carbon700;BCR_co2_2000;NKV_el03;NKV_el03_carbon215_invcostTud;NKV_el03_carbon700tpr0_invcostTud;NKV_el03_carbon700tpr0;addtl_pkwkm_el03;cost_co2_orig;cost_co2_el03;investmentCost_tud;addtl_pkwkm_from_ttime;NKV_elTtime_carbon215_invcostTud;NKV_elTtime_carbon700tpr0_invcostTud;NKV_elTtime_carbon2000_invcostTud;remark_0;remark_1;remark_2;remark_3;remark_4
A20-G10-NI-SH;;VB;NB4;161.0;131.53;143.95;-785.233;90786.067;-326.34;5305.683;2737.176;19000.0;644.0;32.954552795031056;1.9383784601355558;1.6896861769340954;1.6896861769340954;1.6896861769340954;1.0932250067607725;1.8621980025426863;0.040104418189946894;0.029984022872012638;1.3523906336608384;711.62;198.59881207206251;407.11813226428285;123456.789;648.0;0.039835779909582765;0.02910856208016608;3.740819618184369E-4
project _name;URL;Einstufung;bautyp;length;Planungsdauer_jahre;Baudauer_jahre;Betriebsdauer_jahre;addtl_pkwkm_orig;addtl_pkwkm_induz;b_fzkm_orig;co2_equivalents_emissions_orig;b_co2_equivalents_orig;b_overall_orig;investmentCost_orig;DTV_Planfall;addtl_lane_km;b_orig_per_km;NKV_orig;NKV_co2;BCR_co2_700;NKV_carbon700;BCR_co2_2000;NKV_el03;NKV_el03_carbon215_invcostTud;NKV_el03_carbon700tpr0_invcostTud;NKV_el03_carbon700tpr0;addtl_pkwkm_el03;cost_co2_orig;cost_co2_el03;investmentCost_tud;addtl_pkwkm_from_ttime;NKV_elTtime_carbon215_invcostTud;NKV_elTtime_carbon700tpr0_invcostTud;NKV_elTtime_carbon2000_invcostTud;remark_0;remark_1;remark_2;remark_3;remark_4
A20-G10-NI-SH;;VB;NB4;161.0;10.0;4.0;42.0;131.53;143.95;-785.233;90786.067;-326.34;5305.683;2737.176;19000.0;644.0;32.954552795031056;1.9383784601355558;3.197887096076323;3.197887096076323;3.197887096076323;1.0932250067607725;1.8621980025426863;0.040104418189946894;0.06342253518464086;2.860591552803066;711.62;198.59881207206251;407.11813226428285;123456.789;648.0;0.039835779909582765;0.06254707439279432;0.03381259427444669
Loading

0 comments on commit 7751d56

Please sign in to comment.