com.conveyal.gtfs.model.Calendar Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gtfs-lib Show documentation
Show all versions of gtfs-lib Show documentation
A library to load and index GTFS feeds of arbitrary size using disk-backed storage
package com.conveyal.gtfs.model;
import com.conveyal.gtfs.GTFSFeed;
import com.conveyal.gtfs.error.DuplicateKeyError;
import com.conveyal.gtfs.loader.DateField;
import com.conveyal.gtfs.loader.Table;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import java.io.IOException;
import java.io.Serializable;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.Map;
public class Calendar extends Entity implements Serializable {
private static final long serialVersionUID = 6634236680822635875L;
public String service_id;
public LocalDate start_date;
public LocalDate end_date;
// Should these be booleans? Oh... the implications.
public int monday;
public int tuesday;
public int wednesday;
public int thursday;
public int friday;
public int saturday;
public int sunday;
public String feed_id;
@Override
public String getId () {
return service_id;
}
/**
* Sets the parameters for a prepared statement following the parameter order defined in
* {@link com.conveyal.gtfs.loader.Table#CALENDAR}. JDBC prepared statement parameters use a one-based index.
*/
@Override
public void setStatementParameters(PreparedStatement statement, boolean setDefaultId) throws SQLException {
int oneBasedIndex = 1;
if (!setDefaultId) statement.setInt(oneBasedIndex++, id);
DateField startDateField = (DateField) Table.CALENDAR.getFieldForName("start_date");
DateField endDateField = ((DateField) Table.CALENDAR.getFieldForName("end_date"));
statement.setString(oneBasedIndex++, service_id);
setIntParameter(statement, oneBasedIndex++, monday);
setIntParameter(statement, oneBasedIndex++, tuesday);
setIntParameter(statement, oneBasedIndex++, wednesday);
setIntParameter(statement, oneBasedIndex++, thursday);
setIntParameter(statement, oneBasedIndex++, friday);
setIntParameter(statement, oneBasedIndex++, saturday);
setIntParameter(statement, oneBasedIndex++, sunday);
startDateField.setParameter(statement, oneBasedIndex++, start_date);
endDateField.setParameter(statement, oneBasedIndex++, end_date);
statement.setString(oneBasedIndex++, null); // description
}
public static class Loader extends Entity.Loader {
private final Map services;
/**
* Create a loader. The map parameter should be an in-memory map that will be modified. We can't write directly
* to MapDB because we modify services as we load calendar dates, and this creates
* ConcurrentModificationExceptions.
*/
public Loader(GTFSFeed feed, Map services) {
super(feed, "calendar");
this.services = services;
}
@Override
protected boolean isRequired() {
return true;
}
@Override
public void loadOneRow() throws IOException {
/* Calendars and Fares are special: they are stored as joined tables rather than simple maps. */
String service_id = getStringField("service_id", true); // TODO service_id can reference either calendar or calendar_dates.
Service service = services.computeIfAbsent(service_id, Service::new);
if (service.calendar != null) {
feed.errors.add(new DuplicateKeyError(tableName, row, "service_id"));
} else {
Calendar c = new Calendar();
c.id = row + 1; // offset line number by 1 to account for 0-based row index
c.service_id = service.service_id;
c.monday = getIntField("monday", true, 0, 1);
c.tuesday = getIntField("tuesday", true, 0, 1);
c.wednesday = getIntField("wednesday", true, 0, 1);
c.thursday = getIntField("thursday", true, 0, 1);
c.friday = getIntField("friday", true, 0, 1);
c.saturday = getIntField("saturday", true, 0, 1);
c.sunday = getIntField("sunday", true, 0, 1);
// TODO check valid dates
c.start_date = getDateField("start_date", true);
c.end_date = getDateField("end_date", true);
c.feed = feed;
c.feed_id = feed.feedId;
service.calendar = c;
}
}
}
public static class Writer extends Entity.Writer {
public Writer(GTFSFeed feed) {
super(feed, "calendar");
}
@Override
protected void writeHeaders() throws IOException {
writer.writeRecord(new String[] {"service_id", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", "start_date", "end_date"});
}
@Override
protected void writeOneRow(Calendar c) throws IOException {
writeStringField(c.service_id);
writeIntField(c.monday);
writeIntField(c.tuesday);
writeIntField(c.wednesday);
writeIntField(c.thursday);
writeIntField(c.friday);
writeIntField(c.saturday);
writeIntField(c.sunday);
writeDateField(c.start_date);
writeDateField(c.end_date);
endRecord();
}
@Override
protected Iterator iterator() {
// wrap an iterator over services
Iterator calIt = Iterators.transform(feed.services.values().iterator(), new Function () {
@Override
public Calendar apply (Service s) {
return s.calendar;
}
});
// not every service has a calendar (e.g. TriMet has no calendars, just calendar dates).
// This is legal GTFS, so skip services with no calendar
return Iterators.filter(calIt, new Predicate () {
@Override
public boolean apply(Calendar c) {
return c != null;
}
});
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy