
org.onebusaway.gtfs.services.MockGtfs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of onebusaway-gtfs Show documentation
Show all versions of onebusaway-gtfs Show documentation
A Java library for reading and writing General Transit Feed Spec feeds
/**
* Copyright (C) 2011 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.gtfs.services;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.onebusaway.gtfs.impl.GtfsRelationalDaoImpl;
import org.onebusaway.gtfs.model.calendar.ServiceDate;
import org.onebusaway.gtfs.serialization.GtfsReader;
import org.onebusaway.gtfs.serialization.mappings.StopTimeFieldMappingFactory;
public class MockGtfs {
private final File _path;
private Map _contentByFileName = new HashMap();
public MockGtfs(File path) {
_path = path;
}
public static MockGtfs create() throws IOException {
File tmpFile = File.createTempFile("MockGtfs-", ".zip");
tmpFile.deleteOnExit();
return new MockGtfs(tmpFile);
}
public File getPath() {
return _path;
}
public void putFile(String fileName, String content) {
_contentByFileName.put(fileName, content.getBytes());
updateZipFile();
}
public void putFile(String fileName, File file) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
FileInputStream in = new FileInputStream(file);
while (true) {
int rc = in.read(buffer);
if (rc == -1) {
break;
}
out.write(buffer, 0, rc);
}
in.close();
_contentByFileName.put(fileName, out.toByteArray());
updateZipFile();
}
public void putLines(String fileName, String... rows) {
StringBuilder b = new StringBuilder();
for (String row : rows) {
b.append(row);
b.append('\n');
}
putFile(fileName, b.toString());
}
public GtfsMutableRelationalDao read() throws IOException {
GtfsReader reader = new GtfsReader();
return read(reader);
}
public GtfsMutableRelationalDao read(GtfsReader reader) throws IOException {
reader.setInputLocation(_path);
GtfsRelationalDaoImpl dao = new GtfsRelationalDaoImpl();
reader.setEntityStore(dao);
try {
reader.run();
} finally {
reader.close();
}
return dao;
}
public void putMinimal() {
putAgencies(1);
putStops(0);
putRoutes(0);
putTrips(0, "", "");
putStopTimes("", "");
}
public void putAgencies(int numberOfRows, String... columns) {
TableBuilder b = new TableBuilder(numberOfRows);
b.addColumnSpec("agency_id", "a$0");
b.addColumnSpec("agency_name", "Agency $0");
b.addColumnSpec("agency_url", "http://agency-$0.gov/");
b.addColumnSpec("agency_timezone", "America/Los_Angeles");
b.addColumnSpec("agency_lang", "en");
b.addColumnSpecs(columns);
putFile("agency.txt", b.build());
}
public void putDefaultAgencies() {
putLines("agency.txt", "agency_id,agency_name,agency_url,agency_timezone",
"1,Metro,http://metro.gov/,America/Los_Angeles");
}
public void putRoutes(int numberOfRows, String... columns) {
TableBuilder b = new TableBuilder(numberOfRows);
b.addColumnSpec("route_id", "r$0");
b.addColumnSpec("route_short_name", "$0");
b.addColumnSpec("route_long_name", "Route $0");
b.addColumnSpec("route_type", "3");
b.addColumnSpecs(columns);
putFile("routes.txt", b.build());
}
public void putDefaultRoutes() {
putDefaultAgencies();
putLines("routes.txt",
"route_id,route_short_name,route_long_name,route_type",
"R10,10,The Ten,3");
}
public void putStops(int numberOfRows, String... columns) {
TableBuilder b = new TableBuilder(numberOfRows);
b.addColumnSpec("stop_id", "s$0");
b.addColumnSpec("stop_name", "Stop $0");
List stopLats = new ArrayList();
List stopLons = new ArrayList();
for (int i = 0; i < numberOfRows; ++i) {
double lat = 47.65383950857904 + 0.004 * i;
double lon = -122.30782950811766;
stopLats.add(Double.toString(lat));
stopLons.add(Double.toString(lon));
}
b.addColumnSpec("stop_lat", stopLats);
b.addColumnSpec("stop_lon", stopLons);
b.addColumnSpecs(columns);
putFile("stops.txt", b.build());
}
public void putDefaultStops() {
putDefaultAgencies();
putLines("stops.txt", "stop_id,stop_name,stop_lat,stop_lon",
"100,The Stop,47.654403,-122.305211",
"200,The Other Stop,47.656303,-122.315436");
}
public void putCalendars(int numberOfServiceIds, String... columns) {
TableBuilder b = new TableBuilder(numberOfServiceIds);
b.addColumnSpec("service_id", "sid$0");
Calendar c = Calendar.getInstance();
ServiceDate startDate = new ServiceDate(c);
b.addColumnSpec("start_date", startDate.getAsString());
c.add(Calendar.MONTH, 3);
ServiceDate endDate = new ServiceDate(c);
b.addColumnSpec("end_date", endDate.getAsString());
b.addColumnSpec("start_date", startDate.getAsString());
String[] days = {
"monday", "tuesday", "wednesday", "thursday", "friday", "saturday",
"sunday"};
for (String day : days) {
b.addColumnSpec(day, "1");
}
List mask = new ArrayList();
columns = b.removeColumn("mask", columns, mask);
if (!mask.isEmpty()) {
Map> valuesByDay = new HashMap>();
for (String day : days) {
valuesByDay.put(day, new ArrayList());
}
for (String maskRow : mask) {
if (maskRow.length() != days.length) {
throw new IllegalArgumentException("invalid calendar.txt mask="
+ maskRow);
}
for (int i = 0; i < maskRow.length(); ++i) {
String day = days[i];
valuesByDay.get(day).add(maskRow.substring(i, i + 1));
}
}
for (String day : days) {
b.addColumnSpec(day, valuesByDay.get(day));
}
}
b.addColumnSpecs(columns);
putFile("calendar.txt", b.build());
}
public void putDefaultCalendar() {
putLines(
"calendars.txt",
"service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date",
"WEEK,1,1,1,1,1,0,0,20110101,20111231");
}
public void putCalendarDates(String... specs) {
List serviceIds = new ArrayList();
List serviceDates = new ArrayList();
List exceptionTypes = new ArrayList();
for (String spec : specs) {
int index = spec.indexOf('=');
if (index == -1) {
throw new IllegalArgumentException("invalid calendar date spec=" + spec);
}
String serviceId = spec.substring(0, index);
String dates = spec.substring(index + 1);
for (String date : dates.split(",")) {
int exceptionType = 1;
if (date.startsWith("-")) {
exceptionType = 2;
date = date.substring(1);
}
serviceIds.add(serviceId);
serviceDates.add(date);
exceptionTypes.add(Integer.toString(exceptionType));
}
}
TableBuilder b = new TableBuilder(serviceIds.size());
b.addColumnSpec("service_id", serviceIds);
b.addColumnSpec("date", serviceDates);
b.addColumnSpec("exception_type", exceptionTypes);
putFile("calendar_dates.txt", b.build());
}
public void putTrips(int numberOfRows, String routeIds, String serviceIds,
String... columns) {
TableBuilder b = new TableBuilder(numberOfRows);
b.addColumnSpec("trip_id", "t$0");
b.addColumnSpec("route_id", routeIds);
b.addColumnSpec("service_id", serviceIds);
b.addColumnSpecs(columns);
putFile("trips.txt", b.build());
}
public void putDefaultTrips() {
putDefaultRoutes();
putDefaultCalendar();
putLines("trips.txt", "route_id,service_id,trip_id", "R10,WEEK,T10-0");
}
public void putStopTimes(String tripIds, String stopIds) {
List tripIdColumn = new ArrayList();
List stopIdColumn = new ArrayList();
List arrivalTimeColumn = new ArrayList();
List departureTimeColumn = new ArrayList();
List stopSequenceColumn = new ArrayList();
String[] expandedTripIds = tripIds.isEmpty() ? new String[0]
: tripIds.split(",");
List> expandedStopIds = new ArrayList>();
if (!stopIds.isEmpty()) {
for (String stopIdsEntry : stopIds.split("\\|")) {
expandedStopIds.add(Arrays.asList(stopIdsEntry.split(",")));
}
}
if (expandedStopIds.size() != 1
&& expandedStopIds.size() != expandedTripIds.length) {
throw new IllegalArgumentException("given " + expandedTripIds.length
+ " trip_id values, expected either 1 or " + expandedTripIds.length
+ " stop_id lists, but instead found " + expandedStopIds.size());
}
int startTime = 9 * 60 * 60;
for (int i = 0; i < expandedTripIds.length; ++i) {
String tripId = expandedTripIds[i];
List specificStopIds = expandedStopIds.get(expandedStopIds.size() == 1
? 0 : i);
int t = startTime;
for (int stopSequence = 0; stopSequence < specificStopIds.size(); stopSequence++) {
String stopId = specificStopIds.get(stopSequence);
tripIdColumn.add(tripId);
stopIdColumn.add(stopId);
stopSequenceColumn.add(Integer.toString(stopSequence));
String timeString = StopTimeFieldMappingFactory.getSecondsAsString(t);
arrivalTimeColumn.add(timeString);
departureTimeColumn.add(timeString);
t += 5 * 60;
}
startTime += 30 * 60;
}
TableBuilder b = new TableBuilder(tripIdColumn.size());
b.addColumnSpec("trip_id", tripIdColumn);
b.addColumnSpec("stop_id", stopIdColumn);
b.addColumnSpec("arrival_time", arrivalTimeColumn);
b.addColumnSpec("departure_time", departureTimeColumn);
b.addColumnSpec("stop_sequence", stopSequenceColumn);
putFile("stop_times.txt", b.build());
}
public void putDefaultStopTimes() {
putDefaultTrips();
putDefaultStops();
putLines("stop_times.txt",
"trip_id,stop_id,stop_sequence,arrival_time,departure_time",
"T10-0,100,0,08:00:00,08:00:00", "T10-0,200,1,09:00:00,09:00:00");
}
private void updateZipFile() {
try {
if (_path.exists()) {
_path.delete();
}
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(_path));
for (Map.Entry entry : _contentByFileName.entrySet()) {
String fileName = entry.getKey();
byte[] content = entry.getValue();
ZipEntry zipEntry = new ZipEntry(fileName);
out.putNextEntry(zipEntry);
out.write(content);
out.closeEntry();
}
out.close();
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
private static class TableBuilder {
private final LinkedHashMap> _columnsAndValues = new LinkedHashMap>();
private final int _numberOfRows;
public TableBuilder(int numberOfRows) {
_numberOfRows = numberOfRows;
}
public void addColumnSpec(String columnName, List values) {
if (values.size() != 1 && values.size() != _numberOfRows) {
throw new IllegalArgumentException("expected 1 or " + _numberOfRows
+ " values but found " + values.size());
}
_columnsAndValues.put(columnName, values);
}
public void addColumnSpec(String columnName, String values) {
addColumnSpec(columnName, expand(values));
}
public void addColumnSpecs(String[] columns) {
for (String spec : columns) {
int index = spec.indexOf('=');
if (index == -1) {
throw new IllegalArgumentException("invalid column spec=" + spec);
}
addColumnSpec(spec.substring(0, index), spec.substring(index + 1));
}
}
public String[] removeColumn(String name, String[] columns,
List values) {
List filtered = new ArrayList();
for (String columnSpec : columns) {
int index = columnSpec.indexOf('=');
if (index == -1) {
throw new IllegalArgumentException("invalid column spec="
+ columnSpec);
}
String columnName = columnSpec.substring(0, index);
if (columnName.equals(name)) {
String columnValue = columnSpec.substring(index + 1);
values.clear();
values.addAll(expand(columnValue));
} else {
filtered.add(columnSpec);
}
}
return filtered.toArray(new String[filtered.size()]);
}
public String build() {
StringBuilder b = new StringBuilder();
buildHeader(b);
buildValues(b);
return b.toString();
}
private void buildHeader(StringBuilder b) {
boolean addComma = false;
for (String columnName : _columnsAndValues.keySet()) {
if (addComma) {
b.append(",");
}
b.append(columnName);
addComma = true;
}
b.append("\n");
}
private void buildValues(StringBuilder b) {
for (int i = 0; i < _numberOfRows; ++i) {
boolean addComma = false;
for (List values : _columnsAndValues.values()) {
if (addComma) {
b.append(",");
}
String value = values.size() > 1 ? values.get(i) : values.get(0);
b.append(value);
addComma = true;
}
b.append("\n");
}
}
private List expand(String values) {
String[] tokens = values.split(",");
if (tokens.length == 1 && tokens[0].contains("$0")) {
String[] expanded = new String[_numberOfRows];
for (int i = 0; i < _numberOfRows; ++i) {
expanded[i] = tokens[0].replaceAll("\\$0", Integer.toString(i));
}
tokens = expanded;
}
if (tokens.length != 1 && tokens.length != _numberOfRows) {
throw new IllegalStateException("expected either 1 or " + _numberOfRows
+ " values but found " + tokens.length + " for \"" + values + "\"");
}
return Arrays.asList(tokens);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy