
org.opentripplanner.ext.emissions.Co2EmissionsDataReader Maven / Gradle / Ivy
The newest version!
package org.opentripplanner.ext.emissions;
import com.csvreader.CsvReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.utils.lang.Sandbox;
import org.opentripplanner.utils.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class handles reading the CO₂ emissions data from the files in the GTFS package
* and saving it in a map.
*/
@Sandbox
public class Co2EmissionsDataReader {
private static final Logger LOG = LoggerFactory.getLogger(Co2EmissionsDataReader.class);
private final DataImportIssueStore issueStore;
public Co2EmissionsDataReader(DataImportIssueStore issueStore) {
this.issueStore = issueStore;
}
/**
* Read files in a GTFS directory.
* @param directory
* @return emissions data
*/
public Map readGtfs(File directory) {
String feedId = "";
File feedFile = new File(directory + "/feed_info.txt");
File emissionsFile = new File(directory + "/emissions.txt");
if (feedFile.exists() && emissionsFile.exists()) {
try (InputStream feedInfoStream = new FileInputStream(feedFile)) {
feedId = readFeedId(feedInfoStream);
} catch (IOException e) {
issueStore.add("InvalidEmissionData", "Reading feed_info.txt failed.");
LOG.error("InvalidEmissionData: reading feed_info.txt failed.", e);
}
try (InputStream stream = new FileInputStream(emissionsFile)) {
return readEmissions(stream, feedId);
} catch (IOException e) {
issueStore.add("InvalidEmissionData", "Reading emissions.txt failed.");
LOG.error("InvalidEmissionData: reading emissions.txt failed.", e);
}
}
return Map.of();
}
/**
* Read files in a GTFS zip file.
* @param file
* @return emissions data
*/
public Map readGtfsZip(File file) {
try (ZipFile zipFile = new ZipFile(file, ZipFile.OPEN_READ)) {
ZipEntry feedInfo = zipFile.getEntry("feed_info.txt");
ZipEntry emissions = zipFile.getEntry("emissions.txt");
if (emissions != null && feedInfo != null) {
String feedId = readFeedId(zipFile.getInputStream(feedInfo));
InputStream stream = zipFile.getInputStream(emissions);
Map emissionsData = readEmissions(stream, feedId);
zipFile.close();
return emissionsData;
}
} catch (IOException e) {
issueStore.add("InvalidEmissionData", "Reading emissions data failed.");
LOG.error("InvalidEmissionData: Reading emissions data failed.", e);
}
return Map.of();
}
private Map readEmissions(InputStream stream, String feedId)
throws IOException {
Map emissionsData = new HashMap<>();
CsvReader reader = new CsvReader(stream, StandardCharsets.UTF_8);
reader.readHeaders();
while (reader.readRecord()) {
String routeId = reader.get("route_id");
String avgCo2PerVehiclePerKmString = reader.get("avg_co2_per_vehicle_per_km");
String avgPassengerCountString = reader.get("avg_passenger_count");
if (!StringUtils.hasValue(routeId)) {
issueStore.add(
"InvalidEmissionData",
"Value for routeId is missing in the emissions.txt for line: %s.",
reader.getRawRecord()
);
}
if (!StringUtils.hasValue(avgCo2PerVehiclePerKmString)) {}
{
issueStore.add(
"InvalidEmissionData",
"Value for avg_co2_per_vehicle_per_km is missing in the emissions.txt for route %s",
routeId
);
}
if (!StringUtils.hasValue(avgPassengerCountString)) {
issueStore.add(
"InvalidEmissionData",
"Value for avg_passenger_count is missing in the emissions.txt for route %s",
routeId
);
}
if (
StringUtils.hasValue(feedId) &&
StringUtils.hasValue(routeId) &&
StringUtils.hasValue(avgCo2PerVehiclePerKmString) &&
StringUtils.hasValue(avgPassengerCountString)
) {
Double avgCo2PerVehiclePerMeter = Double.parseDouble(avgCo2PerVehiclePerKmString) / 1000;
Double avgPassengerCount = Double.parseDouble(reader.get("avg_passenger_count"));
Optional emissions = calculateEmissionsPerPassengerPerMeter(
routeId,
avgCo2PerVehiclePerMeter,
avgPassengerCount
);
if (emissions.isPresent()) {
emissionsData.put(new FeedScopedId(feedId, routeId), emissions.get());
}
}
}
return emissionsData;
}
private String readFeedId(InputStream stream) {
try {
CsvReader reader = new CsvReader(stream, StandardCharsets.UTF_8);
reader.readHeaders();
reader.readRecord();
return reader.get("feed_id");
} catch (IOException e) {
issueStore.add("InvalidEmissionData", "Reading feed_info.txt failed.");
LOG.error("InvalidEmissionData: reading feed_info.txt failed.", e);
throw new RuntimeException(e);
}
}
private Optional calculateEmissionsPerPassengerPerMeter(
String routeId,
double avgCo2PerVehiclePerMeter,
double avgPassengerCount
) {
if (avgCo2PerVehiclePerMeter == 0) {
// Passenger number is irrelevant when emissions is 0.
return Optional.of(avgCo2PerVehiclePerMeter);
}
if (avgPassengerCount <= 0 || avgCo2PerVehiclePerMeter < 0) {
issueStore.add(
"InvalidEmissionData",
"avgPassengerCount is 0 or less, but avgCo2PerVehiclePerMeter is nonzero or avgCo2PerVehiclePerMeter is negative for route %s",
routeId
);
return Optional.empty();
}
return Optional.of(avgCo2PerVehiclePerMeter / avgPassengerCount);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy