diff --git a/pom.xml b/pom.xml index 64041c04e..3a7fab6a6 100644 --- a/pom.xml +++ b/pom.xml @@ -272,7 +272,7 @@ com.github.ibi-group gtfs-lib - e9de250 + 5e004388b2473c391412fdd4954068c35186e231 diff --git a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java index 5b3eed845..5d27a495f 100644 --- a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java +++ b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResource.java @@ -51,6 +51,8 @@ public class MtcFeedResource implements ExternalFeedResource { public static final String TEST_AGENCY = "test-agency"; public static final String AGENCY_ID_FIELDNAME = "AgencyId"; public static final String RESOURCE_TYPE = "MTC"; + public static final String STOP_CODE_PRIMARY_PREFIX_FIELD_NAME = "PrimaryPrefix"; + public static final String STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME = "SecondaryPrefixes"; private String rtdApi, s3Bucket, s3Prefix; @@ -337,4 +339,14 @@ static String convertRtdString(String s) { if ("null".equals(s)) return ""; return s; } + + public static String getFieldValue(Map> properties, String fieldName) { + Map values = properties.get(RESOURCE_TYPE); + return values.get(fieldName); + } + + public static List getSecondaryStopCodePrefixes(Map> properties) { + String secondaryStopPrefixValue = MtcFeedResource.getFieldValue(properties, MtcFeedResource.STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME); + return (secondaryStopPrefixValue == null) ? null : List.of(secondaryStopPrefixValue.split(",")); + } } diff --git a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java index 4e66fe541..91fad0452 100644 --- a/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java +++ b/src/main/java/com/conveyal/datatools/manager/extensions/mtc/RtdCarrier.java @@ -9,6 +9,8 @@ import java.lang.reflect.Field; +import static com.conveyal.datatools.manager.extensions.mtc.MtcFeedResource.STOP_CODE_PRIMARY_PREFIX_FIELD_NAME; +import static com.conveyal.datatools.manager.extensions.mtc.MtcFeedResource.STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME; import static com.conveyal.datatools.manager.models.ExternalFeedSourceProperty.constructId; /** @@ -70,6 +72,12 @@ public class RtdCarrier { @JsonProperty String EditedDate; + @JsonProperty + String PrimaryPrefix; + + @JsonProperty + String SecondaryPrefixes; + /** Empty constructor needed for serialization (also used to create empty carrier). */ public RtdCarrier() { } @@ -94,6 +102,8 @@ public RtdCarrier(FeedSource source) { AgencyEmail = getValueForField(source, "AgencyEmail"); AgencyUrl = getValueForField(source, "AgencyUrl"); AgencyFareUrl = getValueForField(source, "AgencyFareUrl"); + PrimaryPrefix = getValueForField(source, STOP_CODE_PRIMARY_PREFIX_FIELD_NAME); + SecondaryPrefixes = getValueForField(source, STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME); } private String getPropId(FeedSource source, String fieldName) { diff --git a/src/main/java/com/conveyal/datatools/manager/models/Deployment.java b/src/main/java/com/conveyal/datatools/manager/models/Deployment.java index aeccae961..201b96f1b 100644 --- a/src/main/java/com/conveyal/datatools/manager/models/Deployment.java +++ b/src/main/java/com/conveyal/datatools/manager/models/Deployment.java @@ -18,6 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.io.ByteStreams; import com.mongodb.client.FindIterable; +import org.apache.logging.log4j.util.Strings; import org.bson.codecs.pojo.annotations.BsonIgnore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -355,7 +356,9 @@ public void dump (File output, boolean includeManifest, boolean includeOsm, bool LOG.error("Could not retrieve file for {}", v.name); throw new RuntimeException(e1); } - ZipEntry e = new ZipEntry(gtfsFile.getName()); + // Determine the entry name for the zip file. + String entryName = getFeedSourceBundleFilename(v, gtfsFile); + ZipEntry e = new ZipEntry(entryName); out.putNextEntry(e); ByteStreams.copy(in, out); try { @@ -417,6 +420,29 @@ public void dump (File output, boolean includeManifest, boolean includeOsm, bool out.close(); } + /** + * Determine the entry name for a GTFS file within the deployment bundle. + * This prioritizes the FeedSource filename if available and valid, otherwise falls back + * to the original GTFS filename derived from the FeedVersion. + * + * @param feedVersion The FeedVersion being processed. + * @param gtfsFile The GTFS file associated with the FeedVersion. + * @return The calculated entry name for the zip file. + */ + public String getFeedSourceBundleFilename(FeedVersion feedVersion, File gtfsFile) { + String gtfsFileName = gtfsFile.getName(); + FeedSource fs = feedVersion.parentFeedSource(); + + if (fs != null && !Strings.isBlank(fs.filename)) { + // Use FeedSource filename if available, ensuring it ends with .zip + LOG.info("Using FeedSource filename for zip entry: {}", gtfsFileName); + return fs.filename.endsWith(".zip") ? fs.filename : fs.filename + ".zip"; + } + // Fallback to the original GTFS filename derived from FeedVersion + LOG.info("Using FeedVersion filename for zip entry: {}", gtfsFileName); + return gtfsFileName; + } + /** Download config from provided URL. */ public String downloadConfig(String configUrl) throws IOException { if (configUrl != null) { diff --git a/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java b/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java index db7eea7a9..c88d6c9d0 100644 --- a/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java +++ b/src/main/java/com/conveyal/datatools/manager/models/FeedSource.java @@ -97,6 +97,9 @@ public String organizationId () { /** The name of this feed source, e.g. MTA New York City Subway */ public String name; + /** An optional display filename for the feed in the bundle, e.g. "agency_transit.zip" */ + public String filename; + /** Is this feed public, i.e. should it be listed on the * public feeds page for download? */ diff --git a/src/main/java/com/conveyal/datatools/manager/models/FeedSourceSummary.java b/src/main/java/com/conveyal/datatools/manager/models/FeedSourceSummary.java index 15f93e57b..1b88b91a5 100644 --- a/src/main/java/com/conveyal/datatools/manager/models/FeedSourceSummary.java +++ b/src/main/java/com/conveyal/datatools/manager/models/FeedSourceSummary.java @@ -42,6 +42,9 @@ public class FeedSourceSummary { public boolean deployable; public boolean isPublic; + /** An optional display filename for the feed in the bundle, e.g. "agency_transit.zip" */ + public String filename; + @JsonSerialize(using = JacksonSerializers.LocalDateIsoSerializer.class) @JsonDeserialize(using = JacksonSerializers.LocalDateIsoDeserializer.class) public LocalDate lastUpdated; @@ -89,6 +92,8 @@ public FeedSourceSummary(String projectId, String organizationId, Document feedS // Convert to local date type for consistency. this.lastUpdated = getLocalDateFromDate(feedSourceDocument.getDate("lastUpdated")); this.url = feedSourceDocument.getString("url"); + // Get optional filename. + this.filename = feedSourceDocument.getString("filename"); } /** @@ -131,6 +136,7 @@ public static List getFeedSourceSummaries(String projectId, S "lastUpdated": 1, "labelIds": 1, "url": 1, + "filename": 1, "noteIds": 1 } }, @@ -154,6 +160,7 @@ public static List getFeedSourceSummaries(String projectId, S "lastUpdated", "labelIds", "url", + "filename", "noteIds") ) ), diff --git a/src/main/java/com/conveyal/datatools/manager/models/FeedVersion.java b/src/main/java/com/conveyal/datatools/manager/models/FeedVersion.java index bb87c6187..0091605cc 100644 --- a/src/main/java/com/conveyal/datatools/manager/models/FeedVersion.java +++ b/src/main/java/com/conveyal/datatools/manager/models/FeedVersion.java @@ -3,6 +3,7 @@ import com.conveyal.datatools.common.status.MonitorableJob; import com.conveyal.datatools.common.utils.Scheduler; import com.conveyal.datatools.manager.DataManager; +import com.conveyal.datatools.manager.extensions.mtc.MtcFeedResource; import com.conveyal.datatools.manager.jobs.ValidateFeedJob; import com.conveyal.datatools.manager.jobs.ValidateMobilityDataFeedJob; import com.conveyal.datatools.manager.jobs.validation.RouteTypeValidatorBuilder; @@ -48,6 +49,8 @@ import java.text.SimpleDateFormat; import java.time.LocalDate; import java.util.Date; +import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -365,15 +368,24 @@ public void validate(MonitorableJob.Status status) { // FIXME: pass status to validate? Or somehow listen to events? status.update("Validating feed...", 33); + FeedSource fs = Persistence.feedSources.getById(this.feedSourceId); + // Validate the feed version. // Certain extensions, if enabled, have extra validators. if (isExtensionEnabled("mtc")) { + Map> properties = fs.externalProperties(); + String primaryStopCodePrefix = MtcFeedResource.getFieldValue(properties, MtcFeedResource.STOP_CODE_PRIMARY_PREFIX_FIELD_NAME); + List secondaryStopCodePrefixes = MtcFeedResource.getSecondaryStopCodePrefixes(properties); validationResult = GTFS.validate(feedLoadResult.uniqueIdentifier, DataManager.GTFS_DATA_SOURCE, RouteTypeValidatorBuilder::buildRouteValidator, - MTCValidator::new + (feed, errorStorage) -> new MTCValidator( + feed, + errorStorage, + primaryStopCodePrefix, + secondaryStopCodePrefixes + ) ); } else { - FeedSource fs = Persistence.feedSources.getById(this.feedSourceId); /* Get feed_id from feed version diff --git a/src/main/java/com/conveyal/datatools/manager/utils/HashUtils.java b/src/main/java/com/conveyal/datatools/manager/utils/HashUtils.java index 7df050e52..a23660b7c 100644 --- a/src/main/java/com/conveyal/datatools/manager/utils/HashUtils.java +++ b/src/main/java/com/conveyal/datatools/manager/utils/HashUtils.java @@ -1,6 +1,5 @@ package com.conveyal.datatools.manager.utils; -import com.conveyal.datatools.manager.extensions.mtc.MtcFeedResource; import org.apache.commons.codec.binary.Hex; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,7 +13,7 @@ public class HashUtils { - public static final Logger LOG = LoggerFactory.getLogger(MtcFeedResource.class); + public static final Logger LOG = LoggerFactory.getLogger(HashUtils.class); /** * Get MD5 hash for the specified file. diff --git a/src/test/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResourceTest.java b/src/test/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResourceTest.java index 3a6cb6a31..07b69eaf5 100644 --- a/src/test/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResourceTest.java +++ b/src/test/java/com/conveyal/datatools/manager/extensions/mtc/MtcFeedResourceTest.java @@ -8,6 +8,7 @@ import com.conveyal.datatools.manager.models.FeedVersion; import com.conveyal.datatools.manager.models.Project; import com.conveyal.datatools.manager.persistence.Persistence; +import com.conveyal.datatools.manager.utils.SqlAssert; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.github.tomakehurst.wiremock.WireMockServer; @@ -18,11 +19,15 @@ import org.junit.jupiter.params.provider.ValueSource; import java.io.IOException; +import java.sql.SQLException; import java.util.Date; import static com.conveyal.datatools.TestUtils.createFeedVersion; import static com.conveyal.datatools.TestUtils.parseJson; import static com.conveyal.datatools.TestUtils.zipFolderFiles; +import static com.conveyal.datatools.manager.extensions.mtc.MtcFeedResource.STOP_CODE_PRIMARY_PREFIX_FIELD_NAME; +import static com.conveyal.datatools.manager.extensions.mtc.MtcFeedResource.STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME; +import static com.conveyal.gtfs.error.NewGTFSErrorType.MISSING_STOP_CODE_PREFIX; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; @@ -99,31 +104,13 @@ void canUpdateFeedExternalPropertiesToMongo() throws IOException { // Set up some entries in the ExternalFeedSourceProperties collection. // This one (AgencyId) should not change. - ExternalFeedSourceProperty agencyIdProp = new ExternalFeedSourceProperty( - feedSource, - "MTC", - "AgencyId", - AGENCY_CODE - ); - Persistence.externalFeedSourceProperties.create(agencyIdProp); + String agencyIdPropId = createExternalFeedSourceProperties("AgencyId", AGENCY_CODE); // This one (AgencyPublicId) should be deleted after this test (not in RTD response). - ExternalFeedSourceProperty agencyPublicIdProp = new ExternalFeedSourceProperty( - feedSource, - "MTC", - "AgencyPublicId", - AGENCY_CODE - ); - Persistence.externalFeedSourceProperties.create(agencyPublicIdProp); + String agencyPublicIdPropId = createExternalFeedSourceProperties("AgencyPublicId", AGENCY_CODE); // This one (AgencyEmail) should be updated with this test. - ExternalFeedSourceProperty agencyEmailProp = new ExternalFeedSourceProperty( - feedSource, - "MTC", - "AgencyEmail", - "old@email.example.com" - ); - Persistence.externalFeedSourceProperties.create(agencyEmailProp); + String agencyEmailPropId = createExternalFeedSourceProperties("AgencyEmail", "old@email.example.com"); // make RTD request and parse the json response JsonNode rtdResponse = parseJson( @@ -137,55 +124,86 @@ void canUpdateFeedExternalPropertiesToMongo() throws IOException { // Also extract desired values from response String responseEmail = rtdResponse.get("AgencyEmail").asText(); String responseAgencyName = rtdResponse.get("AgencyName").asText(); + String responsePrimaryPrefix = rtdResponse.get(STOP_CODE_PRIMARY_PREFIX_FIELD_NAME).asText(); + String responseSecondaryPrefixes = rtdResponse.get(STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME).asText(); // Update MTC Feed properties in Mongo based response. new MtcFeedResource().updateMongoExternalFeedProperties(feedSource, rtdResponse); // Existing field AgencyId should retain the same value. - ExternalFeedSourceProperty updatedAgencyIdProp = Persistence.externalFeedSourceProperties.getById(agencyIdProp.id); - assertThat(updatedAgencyIdProp.value, equalTo(agencyIdProp.value)); + ExternalFeedSourceProperty updatedAgencyIdProp = Persistence.externalFeedSourceProperties.getById(agencyIdPropId); + assertThat(updatedAgencyIdProp.value, equalTo(AGENCY_CODE)); // Existing field AgencyEmail should be updated from RTD response. - ExternalFeedSourceProperty updatedEmailProp = Persistence.externalFeedSourceProperties.getById(agencyEmailProp.id); + ExternalFeedSourceProperty updatedEmailProp = Persistence.externalFeedSourceProperties.getById(agencyEmailPropId); assertThat(updatedEmailProp.value, equalTo(responseEmail)); - // New field AgencyName (not set up above) from RTD response should be added to Mongo. - ExternalFeedSourceProperty newAgencyNameProp = Persistence.externalFeedSourceProperties.getOneFiltered( - and( - eq("feedSourceId", feedSource.id), - eq("resourceType", "MTC"), - eq("name", "AgencyName") ) - ); - assertThat(newAgencyNameProp, notNullValue()); - assertThat(newAgencyNameProp.value, equalTo(responseAgencyName)); + checkForRTDPropInMongo("AgencyName", responseAgencyName); + String primaryPrefixPropId = checkForRTDPropInMongo(STOP_CODE_PRIMARY_PREFIX_FIELD_NAME, responsePrimaryPrefix); + String secondaryPrefixesPropId = checkForRTDPropInMongo(STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME, responseSecondaryPrefixes); // Removed field AgencyPublicId from RTD should be deleted from Mongo. - ExternalFeedSourceProperty removedPublicIdProp = Persistence.externalFeedSourceProperties.getById(agencyPublicIdProp.id); + ExternalFeedSourceProperty removedPublicIdProp = Persistence.externalFeedSourceProperties.getById(agencyPublicIdPropId); assertThat(removedPublicIdProp, nullValue()); - Persistence.externalFeedSourceProperties.removeById(agencyIdProp.id); - Persistence.externalFeedSourceProperties.removeById(agencyPublicIdProp.id); - Persistence.externalFeedSourceProperties.removeById(agencyEmailProp.id); + Persistence.externalFeedSourceProperties.removeById(agencyIdPropId); + Persistence.externalFeedSourceProperties.removeById(agencyPublicIdPropId); + Persistence.externalFeedSourceProperties.removeById(agencyEmailPropId); + Persistence.externalFeedSourceProperties.removeById(primaryPrefixPropId); + Persistence.externalFeedSourceProperties.removeById(secondaryPrefixesPropId); + } + + /** + * Check that new fields from RTD response are added to Mongo. + */ + private String checkForRTDPropInMongo(String propName, String expectedValue) { + ExternalFeedSourceProperty prop = Persistence.externalFeedSourceProperties.getOneFiltered( + and( + eq("feedSourceId", feedSource.id), + eq("resourceType", "MTC"), + eq("name", propName) + ) + ); + assertThat(prop, notNullValue()); + assertThat(prop.value, equalTo(expectedValue)); + return prop.id; } @Test void shouldTolerateNullObjectInExternalPropertyAgencyId() throws IOException { // Add an entry in the ExternalFeedSourceProperties collection // with AgencyId value set to null. - ExternalFeedSourceProperty agencyIdProp = new ExternalFeedSourceProperty( - feedSource, - "MTC", - "AgencyId", - null - ); - Persistence.externalFeedSourceProperties.create(agencyIdProp); - + String agencyIdProp = createExternalFeedSourceProperties("AgencyId", null); // Trigger the feed update process (it should not upload anything to S3). - FeedVersion feedVersion = createFeedVersion(feedSource, zipFolderFiles("mini-bart-new")); + FeedVersion feedVersion = createFeedVersion(feedSource, zipFolderFiles("mtc-feed-resource-test")); MtcFeedResource mtcFeedResource = new MtcFeedResource(); assertDoesNotThrow(() -> mtcFeedResource.feedVersionCreated(feedVersion, null)); + Persistence.externalFeedSourceProperties.removeById(agencyIdProp); + } - Persistence.externalFeedSourceProperties.removeById(agencyIdProp.id); + @Test + void shouldValidateStopCodePrefixes() throws IOException, SQLException { + String primaryPrefixPropId = createExternalFeedSourceProperties(STOP_CODE_PRIMARY_PREFIX_FIELD_NAME, "primary-1"); + String secondaryPrefixesPropId = createExternalFeedSourceProperties(STOP_CODE_SECONDARY_PREFIXES_FIELD_NAME, "secondary-1,secondary-2"); + + FeedVersion feedVersion = createFeedVersion(feedSource, zipFolderFiles("mtc-feed-resource-test")); + MtcFeedResource mtcFeedResource = new MtcFeedResource(); + assertDoesNotThrow(() -> mtcFeedResource.feedVersionCreated(feedVersion, null)); + SqlAssert sqlAssert = new SqlAssert(feedVersion); + sqlAssert.errors.assertCount(1, String.format("error_type='%s'", MISSING_STOP_CODE_PREFIX.name())); + Persistence.externalFeedSourceProperties.removeById(primaryPrefixPropId); + Persistence.externalFeedSourceProperties.removeById(secondaryPrefixesPropId); + } + + private String createExternalFeedSourceProperties(String name, String value) { + ExternalFeedSourceProperty prop = new ExternalFeedSourceProperty( + feedSource, + "MTC", + name, + value + ); + Persistence.externalFeedSourceProperties.create(prop); + return prop.id; } @ParameterizedTest diff --git a/src/test/java/com/conveyal/datatools/manager/jobs/DeployJobTest.java b/src/test/java/com/conveyal/datatools/manager/jobs/DeployJobTest.java index e0504d589..9cdf6b0f0 100644 --- a/src/test/java/com/conveyal/datatools/manager/jobs/DeployJobTest.java +++ b/src/test/java/com/conveyal/datatools/manager/jobs/DeployJobTest.java @@ -9,6 +9,8 @@ import com.conveyal.datatools.manager.auth.Auth0UserProfile; import com.conveyal.datatools.manager.models.Deployment; import com.conveyal.datatools.manager.models.EC2Info; +import com.conveyal.datatools.manager.models.FeedSource; +import com.conveyal.datatools.manager.models.FeedVersion; import com.conveyal.datatools.manager.models.OtpServer; import com.conveyal.datatools.manager.models.Project; import com.conveyal.datatools.manager.persistence.Persistence; @@ -18,6 +20,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Date; @@ -26,6 +29,7 @@ import static com.conveyal.datatools.TestUtils.getBooleanEnvVar; import static com.zenika.snapshotmatcher.SnapshotMatcher.matchesSnapshot; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -90,6 +94,41 @@ void canDownloadConfigs() throws IOException { assertNotNull(deployment.downloadConfig(deployment.customRouterConfigUrl)); } + /** + * Tests that the bundle filename is correctly determined. + */ + @Test + public void canGetFeedSourceBundleFilename() throws IOException { + FeedSource feedSource = new FeedSource("Test FeedSource"); + feedSource.projectId = project.id; + FeedVersion feedVersion = new FeedVersion(feedSource); + File gtfsFile = File.createTempFile("test-gtfs-", ".zip"); + var gtfsFileName = gtfsFile.getName(); + gtfsFile.deleteOnExit(); + + feedSource.filename = "gtfs_from_source.zip"; + Persistence.feedSources.create(feedSource); + assertEquals("gtfs_from_source.zip", deployment.getFeedSourceBundleFilename(feedVersion, gtfsFile)); + + feedSource.filename = "gtfs_from_source"; + Persistence.feedSources.replace(feedSource.id, feedSource); + assertEquals("gtfs_from_source.zip", deployment.getFeedSourceBundleFilename(feedVersion, gtfsFile)); + + feedSource.filename = " "; + Persistence.feedSources.replace(feedSource.id, feedSource); + assertEquals(gtfsFileName, deployment.getFeedSourceBundleFilename(feedVersion, gtfsFile)); + + feedSource.filename = null; + Persistence.feedSources.replace(feedSource.id, feedSource); + assertEquals(gtfsFileName, deployment.getFeedSourceBundleFilename(feedVersion, gtfsFile)); + + FeedVersion versionWithNullSource = new FeedVersion(); + assertEquals(gtfsFileName, deployment.getFeedSourceBundleFilename(versionWithNullSource, gtfsFile)); + + Persistence.feedVersions.removeById(feedVersion.id); + Persistence.feedSources.removeById(feedSource.id); + } + /** * Tests that the otp-runner manifest and user data for a graph build + run server instance can be generated * properly diff --git a/src/test/resources/com/conveyal/datatools/gtfs/mtc-feed-resource-test/agency.txt b/src/test/resources/com/conveyal/datatools/gtfs/mtc-feed-resource-test/agency.txt new file mode 100644 index 000000000..665ceeec3 --- /dev/null +++ b/src/test/resources/com/conveyal/datatools/gtfs/mtc-feed-resource-test/agency.txt @@ -0,0 +1,2 @@ +agency_id,agency_name,agency_url,agency_timezone,agency_lang +BART,Bay Area Rapid Transit,http://www.bart.gov,America/Los_Angeles,en diff --git a/src/test/resources/com/conveyal/datatools/gtfs/mtc-feed-resource-test/stops.txt b/src/test/resources/com/conveyal/datatools/gtfs/mtc-feed-resource-test/stops.txt new file mode 100644 index 000000000..d8997a83b --- /dev/null +++ b/src/test/resources/com/conveyal/datatools/gtfs/mtc-feed-resource-test/stops.txt @@ -0,0 +1,183 @@ +"stop_id","stop_code","stop_name","stop_desc","stop_lat","stop_lon","zone_id","plc_url","location_type","parent_station" +"LAKE","stop-code-1","Lake Merritt","","37.797322","-122.265247","LAKE","","0","place_LAKE" +"FTVL","primary-1-stop-code-2","Fruitvale","","37.774841","-122.224081","FTVL","","0","place_FTVL" +"COLS","secondary-1-stop-code-3","Coliseum","","37.753576","-122.196716","COLS","","0","place_COLS" +"SANL","secondary-2-stop-code-4","San Leandro","","37.721784","-122.160740","SANL","","0","place_SANL" +"BAYF","","Bay Fair","","37.696908","-122.126446","BAYF","","0","place_BAYF" +"HAYW","","Hayward","","37.669699","-122.086958","HAYW","","0","place_HAYW" +"SHAY","","South Hayward","","37.634340","-122.057182","SHAY","","0","place_SHAY" +"UCTY","","Union City","","37.590735","-122.017248","UCTY","","0","place_UCTY" +"FRMT","","Fremont","","37.557480","-121.976619","FRMT","","0","place_FRMT" +"ROCK","","Rockridge","","37.844755","-122.251235","ROCK","","0","place_ROCK" +"ORIN","","Orinda","","37.878481","-122.183667","ORIN","","0","place_ORIN" +"LAFY","","Lafayette","","37.893183","-122.124620","LAFY","","0","place_LAFY" +"WCRK","","Walnut Creek","","37.905791","-122.067327","WCRK","","0","place_WCRK" +"PHIL","","Pleasant Hill / Contra Costa Centre","","37.928434","-122.055971","PHIL","","0","place_PHIL" +"CONC","","Concord","","37.973757","-122.029072","CONC","","0","place_CONC" +"NCON","","North Concord / Martinez","","38.003383","-122.024512","NCON","","0","place_NCON" +"PITT","","Pittsburg / Bay Point","","38.018910","-121.944236","PITT","","0","place_PITT" +"PCTR","","Pittsburg Center","","38.016847","-121.889062","PCTR","","0","place_PCTR" +"ANTC","","Antioch","","37.995373","-121.780346","ANTC","","0","place_ANTC" +"OAKL","","Oakland International Airport Station","","37.713268","-122.212200","OAKL","","0","" +"12TH","","12th Street / Oakland City Center","","37.803482","-122.271630","12TH","","0","place_12TH" +"19TH","","19th Street Oakland","","37.808078","-122.268758","19TH","","0","place_19TH" +"MCAR","","MacArthur","","37.828803","-122.267105","MCAR","","0","place_MCAR" +"CAST","","Castro Valley","","37.690737","-122.075601","CAST","","0","place_CAST" +"WDUB","","West Dublin / Pleasanton","","37.699721","-121.928277","WDUB","","0","place_WDUB" +"DUBL","","Dublin / Pleasanton","","37.701646","-121.899229","DUBL","","0","place_DUBL" +"WOAK","","West Oakland","","37.804888","-122.295151","WOAK","","0","place_WOAK" +"EMBR","","Embarcadero","","37.792762","-122.397037","EMBR","","0","place_EMBR" +"MONT","","Montgomery Street","","37.789173","-122.401587","MONT","","0","place_MONT" +"POWL","","Powell Street","","37.784606","-122.407331","POWL","","0","place_POWL" +"CIVC","","Civic Center / UN Plaza","","37.779408","-122.413826","CIVC","","0","place_CIVC" +"16TH","","16th Street / Mission","","37.765173","-122.419704","16TH","","0","place_16TH" +"24TH","","24th Street / Mission","","37.752419","-122.418468","24TH","","0","place_24TH" +"GLEN","","Glen Park","","37.733235","-122.433515","GLEN","","0","place_GLEN" +"BALB","","Balboa Park","","37.721747","-122.447457","BALB","","0","place_BALB" +"DALY","","Daly City","","37.706259","-122.468908","DALY","","0","place_DALY" +"ASHB","","Ashby","","37.853072","-122.269771","ASHB","","0","place_ASHB" +"DBRK","","Downtown Berkeley","","37.870110","-122.268109","DBRK","","0","place_DBRK" +"NBRK","","North Berkeley","","37.874005","-122.283523","NBRK","","0","place_NBRK" +"PLZA","","El Cerrito Plaza","","37.902610","-122.298920","PLZA","","0","place_PLZA" +"DELN","","El Cerrito Del Norte","","37.925184","-122.316892","DELN","","0","place_DELN" +"RICH","","Richmond","","37.936758","-122.353047","RICH","","0","place_RICH" +"WARM","","Warm Springs / South Fremont","","37.502285","-121.939395","WARM","","0","place_WARM" +"MLPT","","Milpitas","","37.410277","-121.891081","MLPT","","0","place_MLPT" +"BERY","","Berryessa / North San Jose","","37.368473","-121.874681","BERY","","0","place_BERY" +"COLM","","Colma","","37.684635","-122.466157","COLM","","0","place_COLM" +"SSAN","","South San Francisco","","37.664462","-122.444211","SSAN","","0","place_SSAN" +"SBRN","","San Bruno","","37.637730","-122.416326","SBRN","","0","place_SBRN" +"MLBR","","Millbrae (Caltrain Transfer Platform)","","37.600237","-122.386757","MLBR","","0","place_MLBR" +"SFIA","","San Francisco International Airport","","37.616091","-122.391954","SFIA","","0","place_SFIA" +"place_LAKE","","Lake Merritt","","37.797322","-122.265247","","https://www.bart.gov/stations/lake","1","" +"place_FTVL","","Fruitvale","","37.774841","-122.224081","","https://www.bart.gov/stations/ftvl","1","" +"place_COLS","","Coliseum","","37.753576","-122.196716","","https://www.bart.gov/stations/cols","1","" +"place_SANL","","San Leandro","","37.721784","-122.160740","","https://www.bart.gov/stations/sanl","1","" +"place_BAYF","","Bay Fair","","37.696908","-122.126446","","https://www.bart.gov/stations/bayf","1","" +"place_HAYW","","Hayward","","37.669699","-122.086958","","https://www.bart.gov/stations/hayw","1","" +"place_SHAY","","South Hayward","","37.634340","-122.057182","","https://www.bart.gov/stations/shay","1","" +"place_UCTY","","Union City","","37.590735","-122.017248","","https://www.bart.gov/stations/ucty","1","" +"place_FRMT","","Fremont","","37.557480","-121.976619","","https://www.bart.gov/stations/frmt","1","" +"place_ROCK","","Rockridge","","37.844755","-122.251235","","https://www.bart.gov/stations/rock","1","" +"place_ORIN","","Orinda","","37.878481","-122.183667","","https://www.bart.gov/stations/orin","1","" +"place_LAFY","","Lafayette","","37.893183","-122.124620","","https://www.bart.gov/stations/lafy","1","" +"place_WCRK","","Walnut Creek","","37.905791","-122.067327","","https://www.bart.gov/stations/wcrk","1","" +"place_PHIL","","Pleasant Hill / Contra Costa Centre","","37.928434","-122.055971","","https://www.bart.gov/stations/phil","1","" +"place_CONC","","Concord","","37.973757","-122.029072","","https://www.bart.gov/stations/conc","1","" +"place_NCON","","North Concord / Martinez","","38.003383","-122.024512","","https://www.bart.gov/stations/ncon","1","" +"place_PITT","","Pittsburg / Bay Point","","38.018910","-121.944236","","https://www.bart.gov/stations/pitt","1","" +"place_PCTR","","Pittsburg Center","","38.016847","-121.889062","","https://www.bart.gov/stations/pctr","1","" +"place_ANTC","","Antioch","","37.995373","-121.780346","","https://www.bart.gov/stations/antc","1","" +"place_12TH","","12th Street / Oakland City Center","","37.803482","-122.271630","","https://www.bart.gov/stations/12th","1","" +"place_19TH","","19th Street Oakland","","37.808078","-122.268758","","https://www.bart.gov/stations/19th","1","" +"place_MCAR","","MacArthur","","37.828803","-122.267105","","https://www.bart.gov/stations/mcar","1","" +"place_CAST","","Castro Valley","","37.690737","-122.075601","","https://www.bart.gov/stations/cast","1","" +"place_WDUB","","West Dublin / Pleasanton","","37.699721","-121.928277","","https://www.bart.gov/stations/wdub","1","" +"place_DUBL","","Dublin / Pleasanton","","37.701646","-121.899229","","https://www.bart.gov/stations/dubl","1","" +"place_WOAK","","West Oakland","","37.804888","-122.295151","","https://www.bart.gov/stations/woak","1","" +"place_EMBR","","Embarcadero","","37.792762","-122.397037","","https://www.bart.gov/stations/embr","1","" +"place_MONT","","Montgomery Street","","37.789173","-122.401587","","https://www.bart.gov/stations/mont","1","" +"place_POWL","","Powell Street","","37.784606","-122.407331","","https://www.bart.gov/stations/powl","1","" +"place_CIVC","","Civic Center / UN Plaza","","37.779408","-122.413826","","https://www.bart.gov/stations/civc","1","" +"place_16TH","","16th Street / Mission","","37.765173","-122.419704","","https://www.bart.gov/stations/16th","1","" +"place_24TH","","24th Street / Mission","","37.752419","-122.418468","","https://www.bart.gov/stations/24th","1","" +"place_GLEN","","Glen Park","","37.733235","-122.433515","","https://www.bart.gov/stations/glen","1","" +"place_BALB","","Balboa Park","","37.721747","-122.447457","","https://www.bart.gov/stations/balb","1","" +"place_DALY","","Daly City","","37.706259","-122.468908","","https://www.bart.gov/stations/daly","1","" +"place_ASHB","","Ashby","","37.853072","-122.269771","","https://www.bart.gov/stations/ashb","1","" +"place_DBRK","","Downtown Berkeley","","37.870110","-122.268109","","https://www.bart.gov/stations/dbrk","1","" +"place_NBRK","","North Berkeley","","37.874005","-122.283523","","https://www.bart.gov/stations/nbrk","1","" +"place_PLZA","","El Cerrito Plaza","","37.902610","-122.298920","","https://www.bart.gov/stations/plza","1","" +"place_DELN","","El Cerrito Del Norte","","37.925184","-122.316892","","https://www.bart.gov/stations/deln","1","" +"place_RICH","","Richmond","","37.936758","-122.353047","","https://www.bart.gov/stations/rich","1","" +"place_WARM","","Warm Springs / South Fremont","","37.502285","-121.939395","","https://www.bart.gov/stations/warm","1","" +"place_MLPT","","Milpitas","","37.410277","-121.891081","","https://www.bart.gov/stations/mlpt","1","" +"place_BERY","","Berryessa / North San Jose","","37.368473","-121.874681","","https://www.bart.gov/stations/bery","1","" +"place_COLM","","Colma","","37.684635","-122.466157","","https://www.bart.gov/stations/colm","1","" +"place_SSAN","","South San Francisco","","37.664462","-122.444211","","https://www.bart.gov/stations/ssan","1","" +"place_SBRN","","San Bruno","","37.637730","-122.416326","","https://www.bart.gov/stations/sbrn","1","" +"place_MLBR","","Millbrae","","37.600237","-122.386757","","https://www.bart.gov/stations/mlbr","1","" +"place_SFIA","","San Francisco International Airport","","37.616091","-122.391954","","https://www.bart.gov/stations/sfia","1","" +"12TH_1","","Enter/Exit: 13th Street @ Broadway (NW)","Broadway @ 13th Street (SW)","37.803899855","-122.271324","","","2","place_12TH" +"12TH_2","","Enter/Exit: 13th Street @ Broadway (SE)","Broadway @ 13th Street (NE)","37.803315739","-122.271689","","","2","place_12TH" +"12TH_3","","Enter/Exit: 12th Street @ Broadway (N)","Broadway @ 13th Street (NW)","37.802391559","-122.272269","","","2","place_12TH" +"12TH_4","","Enter/Exit: Oakland City Center","Broadway @ 12th Street (NW)","37.803828455","-122.271861","","","2","place_12TH" +"12TH_5","","Enter/Exit: Frank Ogawa Plaza","Broadway @ 12th Street (NE)","37.804768858","-122.271305","","","2","place_12TH" +"12TH_6","","Enter/Exit: 12th Street @ Broadway","Broadway @ 14th Street (NW)","37.802483563","-122.272503","","","2","place_12TH" +"12TH_7","","Enter/Exit: 14th Street @ Broadway","14th Street (NE)","37.80425355","-122.270789","","","2","place_12TH" +"12TH_8","","Enter/Exit: 13th Street @ Broadway","13th Street (NE)","37.803407437","-122.271917","","","2","place_12TH" +"16TH_1","","Enter/Exit : 16th Street @ Mission Street (NE)","16th Street @ Mission Street (NE)","37.765279205","-122.41933807","","","2","place_16TH" +"16TH_2","","Enter/Exit : 16th Street @ Mission Street (SW)","16th Street @ Mission Street (SW)","37.764742121","-122.42004455","","","2","place_16TH" +"19TH_1","","Enter/Exit : Broadway @ 19th Street (South East)","Broadway @ 19th Street (South East)","37.808416009","-122.26851746","","","2","place_19TH" +"19TH_2","","Enter/Exit : Broadway @ 17th Street (West)","Broadway @ 17th Street (West)","37.807281706","-122.26978798","","","2","place_19TH" +"19TH_3","","Enter/Exit : Broadway @ 17th Street (East)","Broadway @ 17th Street (East)","37.806916005","-122.26945171","","","2","place_19TH" +"19TH_4","","Enter/Exit : Broadway @ 20th Street (West)","Broadway @ 20th Street (West)","37.808859155","-122.26849781","","","2","place_19TH" +"19TH_5","","Enter/Exit : Broadway @ 19th Street (South West)","Broadway @ 19th Street (South West)","37.807522576","-122.26907679","","","2","place_19TH" +"19TH_6","","Enter/Exit : 20th Street Entrance (East)","20th Street Entrance (East)","37.808975066","-122.26785938","","","2","place_19TH" +"24TH_1","","Enter/Exit : 24th Street @ Mission Street (NE)","24th Street @ Mission Street (NE)","37.752479","-122.418098","","","2","place_24TH" +"24TH_2","","Enter/Exit : 24th Street @ Mission Street (SW)","24th Street @ Mission Street (SW)","37.751936","-122.418814","","","2","place_24TH" +"ASHB_1","","Enter/Exit : Pedestrian station entrance (WEST)","Pedestrian station entrance","37.853056","-122.269977","","","2","place_ASHB" +"BALB_1","","Enter/Exit : Geneva Ave (West)","Geneva Ave (South)","37.721974","-122.447499","","","2","place_BALB" +"BALB_2","","Enter/Exit : Geneva Ave (East)","Geneva Ave (North)","37.721954","-122.447314","","","2","place_BALB" +"BAYF_1","","Enter/Exit : Pedestrian underpass (SW)","Pedestrian underpass (SW)","37.696868","-122.126976","","","2","place_BAYF" +"BAYF_2","","Enter/Exit : Pedestrian underpass (NW)","Pedestrian underpass (NW)","37.697079","-122.12646","","","2","place_BAYF" +"CAST_1","","Enter/Exit : Station entrance","Station entrance","37.691351","-122.075931","","","2","place_CAST" +"CIVC_1","","Enter/Exit : UN Plaza Stairs","UN Plaza Stairs","37.779755","-122.414238","","","2","place_CIVC" +"CIVC_2","","Enter/Exit : Market Street (E Middle)","Market Street (E Middle)","37.779519","-122.413575","","","2","place_CIVC" +"CIVC_3","","Enter/Exit : Market Street @ 7th Street (NW)","Market Street @ 7th Street (NW)","37.780351","-122.412888","","","2","place_CIVC" +"CIVC_4","","Enter/Exit : Market Street @ 7th Street (NE)","Market Street @ 7th Street (NE)","37.780132","-122.412787","","","2","place_CIVC" +"CIVC_5","","Enter/Exit : Market Street @ Hyde Street (SW)","Market Street @ Hyde Street (SW)","37.778953","-122.414656","","","2","place_CIVC" +"CIVC_6","","Enter/Exit : Market Street @ 8th Street (SE)","Market Street @ 8th Street (SE)","37.778811","-122.414464","","","2","place_CIVC" +"CIVC_7","","Enter/Exit : Market Street @ Grove Street (SE)","Market Street @ Grove Street (SE)","37.778689","-122.415076","","","2","place_CIVC" +"CIVC_8","","Enter/Exit : Market Street South of 8th Street","Market Street South of 8th Street","37.778396","-122.414934","","","2","place_CIVC" +"COLM_2","","Enter/Exit : West Entrance","West Entrance","37.684757","-122.466056","","","2","place_COLM" +"COLS_1","","Enter/Exit : Station entrance (South)","Station entrance (South)","37.753823","-122.197226","","","2","place_COLS" +"COLS_2","","Enter/Exit : Station entrance (North)","Station entrance (North)","37.753998","-122.196777","","","2","place_COLS" +"COLS_4","","Enter/Exit : Oakland Airport Connector entrance","Oakland Airport Connector entrance","37.75278901","-122.1957663","","","2","place_COLS" +"CONC_1","","Enter/Exit : East entrance","East entrance","37.973601","-122.029093","","","2","place_CONC" +"CONC_2","","Enter/Exit : West entrance","West entrance","37.97358","-122.029393","","","2","place_CONC" +"DBRK_1","","Enter/Exit : Shattuck Ave @ Allston Way (West)","Shattuck Ave @ Allston Way (West)","37.869492","-122.268173","","","2","place_DBRK" +"DBRK_2","","Enter/Exit : Shattuck Ave @ Allston Way (East)","Shattuck Ave @ Allston Way (East)","37.869703","-122.267754","","","2","place_DBRK" +"DBRK_3","","Enter/Exit : Shattuck Ave @ Addison Street (West)","Shattuck Ave @ Addison Street (West)","37.871002","-122.268361","","","2","place_DBRK" +"DBRK_4","","Enter/Exit : Shattuck Ave @ Addison Street (East)","Shattuck Ave @ Addison Street (East)","37.871009","-122.268129","","","2","place_DBRK" +"EMBR_1","","Enter/Exit : Market @ Spear Street (SE)","Market @ Spear Street (SE)","37.793523","-122.395835","","","2","place_EMBR" +"EMBR_2","","Enter/Exit : Market @ Drumm Street (NE)","Market @ Drumm Street (NE)","37.793669","-122.396016","","","2","place_EMBR" +"EMBR_3","","Enter/Exit : Market @ Davis Street (North)","Market @ Davis Street (North)","37.792886","-122.39701","","","2","place_EMBR" +"EMBR_4","","Enter/Exit : Market Street @ Main Street (South)","Market Street @ Main Street (South)","37.792892","-122.396619","","","2","place_EMBR" +"EMBR_5","","Enter/Exit : Market Street @ Front Street (NW)","Market Street @ Front Street (NW)","37.792198","-122.397884","","","2","place_EMBR" +"EMBR_6","","Enter/Exit : Market Street @ Fremont Street (SW)","Market Street @ Fremont Street (SW)","37.792072","-122.397644","","","2","place_EMBR" +"FTVL_2","","Enter/Exit : Station entrance (North)","Station entrance (North)","37.775038","-122.224196","","","2","place_FTVL" +"FTVL_3","","Enter/Exit : Station entrance (South)","Station entrance (South)","37.774847","-122.22437","","","2","place_FTVL" +"FRMT_1","","Enter/Exit : Station entrance (North)","Station entrance (North)","37.557508","-121.976412","","","2","place_FRMT" +"FRMT_2","","Enter/Exit : Station entrance (South)","Station entrance (South)","37.557397","-121.976701","","","2","place_FRMT" +"GLEN_1","","Enter/Exit : Station entrance","Station entrance","37.733176","-122.43387","","","2","place_GLEN" +"LAKE_1","","Enter/Exit : Oak Street @ 8th Street (SW)","Oak Street @ 8th Street (SW)","37.797109","-122.265574","","","2","place_LAKE" +"LAKE_2","","Enter/Exit : Oak Street @ 8th Street (SE)","Oak Street @ 8th Street (SE)","37.797067","-122.265151","","","2","place_LAKE" +"LAKE_3","","Enter/Exit : Oak Street @ 9th Street (NE)","Oak Street @ 9th Street (NE)","37.797384","-122.264819","","","2","place_LAKE" +"LAKE_4","","Enter/Exit : 8th Street @ Fallon St (East)","Oak Street@8th St €","37.796765","-122.264276","","","2","place_LAKE" +"MLBR_5","","Enter/Exit : Station entrance (SW)","Station entrance (SW)","37.599939","-122.387135","","","2","place_MLBR" +"MLBR_2","","Enter/Exit : Station entrance (NE)","Station entrnce (NE)","37.600452","-122.386433","","","2","place_MLBR" +"MONT_1","","Enter/Exit : Market @ Post Street (NW)","Market @ Post Street (NW)","37.788924306","-122.40218957","","","2","place_MONT" +"MONT_2","","Enter/Exit : Market (SW)","Market (SW)","37.788512","-122.402155","","","2","place_MONT" +"MONT_3","","Enter/Exit : Market @ Montgomery Street (NE)","Market @ Montgomery Street (NE)","37.789179","-122.40175","","","2","place_MONT" +"MONT_4","","Enter/Exit : Market @ 2nd Street (South)","Market @ 2nd Street (South)","37.789407","-122.401038","","","2","place_MONT" +"MONT_5","","Enter/Exit : Sutter Street","Sutter Street","37.78995","-122.400711","","","2","place_MONT" +"MONT_6","","Enter/Exit : Sansome Street","Sansome Street","37.790503","-122.40069","","","2","place_MONT" +"MONT_7","","Enter/Exit : Market Street (SE)","Market Street (SE)","37.789816","-122.400508","","","2","place_MONT" +"POWL_1","","Enter/Exit : Market Street @ 4th Street (NE)","Market Street @ 4th Street (NE)","37.786037872","-122.40566443","","","2","place_POWL" +"POWL_2","","Enter/Exit : Market Street @ 4th Street (SE)","Market Street @ 4th Street (SE)","37.78590866","-122.40552017","","","2","place_POWL" +"POWL_3","","Enter/Exit : Stockton Street","Stockton Street","37.785864","-122.406341","","","2","place_POWL" +"POWL_4","","Enter/Exit : Market Street @ Ellis Street","Market Street @ Ellis Street","37.785432","-122.406427","","","2","place_POWL" +"POWL_5","","Enter/Exit : Market Street @ 4th Street (South)","Market Street @ 4th Street (South)","37.785256","-122.406301","","","2","place_POWL" +"POWL_6","","Enter/Exit : Market Street @ 5th Street (NE)","Market Street @ 5th Street (NE)","37.78438523","-122.40742314","","","2","place_POWL" +"POWL_7","","Enter/Exit : Escalator to Market Street and Cable Cars","Escalator to Market Street and Cable Cars","37.784562","-122.40777","","","2","place_POWL" +"POWL_8","","Enter/Exit : Market Street @ 5th Street","Market Street @ 5th Street","37.783715","-122.408259","","","2","place_POWL" +"SBRN_3","","Enter/Exit : Station entrance (East)","Station entrance (East)","37.637794217","-122.41616622","","","2","place_SBRN" +"SBRN_4","","Enter/Exit : Station entrance (West)","Station entrance (West)","37.63774422","-122.41641365","","","2","place_SBRN" +"SFIA_1","","Enter/Exit : Station entrance","Station entrance","37.615911","-122.392665","","","2","place_SFIA" +"SHAY_3","","Enter/Exit : Station entrance (East)","Station entrance (East)","37.634562","-122.056826","","","2","place_SHAY" +"PITT_1","","Enter/Exit : Station entrance (South)","Station entrance (South)","38.018237","-121.945339","","","2","place_PITT" +"DELN_1","","Enter/Exit : Station entrance (North)","Station entrance (North)","37.925323","-122.317023","","","2","place_DELN" +"DELN_2","","Enter/Exit : Station entrance (South)","Station entrance (South)","37.924976","-122.316747","","","2","place_DELN" +"MLPT_1","","Enter/Exit: Station entrance","Station entrance","37.410155","-121.890683","","","2","place_MLPT" +"BERY_1","","Enter/Exit: Station entrance","Station entrance","37.368488","-121.874458","","","2","place_BERY" diff --git a/src/test/resources/com/conveyal/datatools/mtc-rtd-mock-responses/__files/rtdGetResponse.json b/src/test/resources/com/conveyal/datatools/mtc-rtd-mock-responses/__files/rtdGetResponse.json index 018834197..d067b4873 100644 --- a/src/test/resources/com/conveyal/datatools/mtc-rtd-mock-responses/__files/rtdGetResponse.json +++ b/src/test/resources/com/conveyal/datatools/mtc-rtd-mock-responses/__files/rtdGetResponse.json @@ -1 +1 @@ -{"AgencyId":"DE","AgencyName":"Dumbarton Express Consortium","AgencyPhone":null,"RttAgencyName":"Dumbarton Express","RttEnabled":"Y","AgencyShortName":"Dumbarton","AddressLat":null,"AddressLon":null,"DefaultRouteType":null,"CarrierStatus":null,"AgencyAddress":"AC Transit (administrator of the Dumbarton Express)","AgencyEmail":"new@email.example.com","AgencyUrl":"https://dumbartonexpress.com","AgencyFareUrl":"","EditedBy":"binh.dam@ibigroup.com","EditedDate":"2021-10-29T16:06:07.914796"} \ No newline at end of file +{"AgencyId":"DE","AgencyName":"Dumbarton Express Consortium","AgencyPhone":null,"RttAgencyName":"Dumbarton Express","RttEnabled":"Y","AgencyShortName":"Dumbarton","AddressLat":null,"AddressLon":null,"DefaultRouteType":null,"CarrierStatus":null,"AgencyAddress":"AC Transit (administrator of the Dumbarton Express)","AgencyEmail":"new@email.example.com","AgencyUrl":"https://dumbartonexpress.com","AgencyFareUrl":"","EditedBy":"binh.dam@ibigroup.com","EditedDate":"2021-10-29T16:06:07.914796","PrimaryPrefix":"primary-1","SecondaryPrefixes":"secondary-1,secondary-2"} \ No newline at end of file