Skip to content

Commit

Permalink
NYS-233 implement partial ADA access for MTA Stations
Browse files Browse the repository at this point in the history
  • Loading branch information
sheldonabrown committed Sep 30, 2023
1 parent 51068f3 commit ef78c67
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import java.util.*;

import static org.onebusaway.gtfs_transformer.csv.CSVUtil.readCsv;
import static org.onebusaway.gtfs_transformer.impl.MTAEntrancesStrategy.WHEELCHAIR_ACCESSIBLE;
import static org.onebusaway.gtfs_transformer.csv.MTAStation.*;

/**
* Based on a CSV of MTAStations set the associated stops accessible as specified.
Expand Down Expand Up @@ -77,18 +77,24 @@ public void run(TransformContext context, GtfsMutableRelationalDao dao) {
"Entrances file does not exist: " + stationsFile.getName());
}

// we have a file, load the contents
// see MTAStationAccessibilityStrategyTest for discussion of how this works
List<MTAStation> stations = getStations();
for (MTAStation station : stations) {
if (station.getAda() == MTAStation.ADA_FULLY_ACCESSIBLE) {
markStopAccessible(dao, station.getStopId(), "N");
markStopAccessible(dao, station.getStopId(), "S");
} else if (station.getAda() == MTAStation.ADA_PARTIALLY_ACCESSIBLE) {
if (station.getAdaNorthBound() == WHEELCHAIR_ACCESSIBLE) {
markStopAccessible(dao, station.getStopId(), "N");
markStopAccessible(dao, station.getStopId(), "", station.getAda());
if (ADA_NOT_ACCESSIBLE == station.getAda()
|| ADA_FULLY_ACCESSIBLE == station.getAda()) {
markStopAccessible(dao, station.getStopId(), "N", station.getAda());
markStopAccessible(dao, station.getStopId(), "S", station.getAda());
} else if (ADA_PARTIALLY_ACCESSIBLE == station.getAda()) {
if (station.getAdaNorthBound() < 0) {
markStopAccessible(dao, station.getStopId(), "N", ADA_NOT_ACCESSIBLE);
} else {
markStopAccessible(dao, station.getStopId(), "N", station.getAdaNorthBound());
}
if (station.getAdaSouthBound() == WHEELCHAIR_ACCESSIBLE) {
markStopAccessible(dao, station.getStopId(), "S");
if (station.getAdaSouthBound() < 0) {
markStopAccessible(dao, station.getStopId(), "S", ADA_NOT_ACCESSIBLE);
} else {
markStopAccessible(dao, station.getStopId(), "S", station.getAdaSouthBound());
}
}
}
Expand All @@ -101,14 +107,15 @@ public void run(TransformContext context, GtfsMutableRelationalDao dao) {

}

private void markStopAccessible(GtfsMutableRelationalDao dao, String stopId, String compassDirection) {
private void markStopAccessible(GtfsMutableRelationalDao dao, String stopId, String compassDirection,
int accessibilityQualifier) {
String unqualifedStopId = stopId + compassDirection;
Stop stopForId = idToStopMap.get(unqualifedStopId);
if (stopForId == null) {
_log.error("no such stop for stopId {}", unqualifedStopId);
return;
}
stopForId.setWheelchairBoarding(WHEELCHAIR_ACCESSIBLE);
stopForId.setWheelchairBoarding(accessibilityQualifier);
this.accessibleStops.add(stopForId);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* Copyright (C) 2023 Cambridge Systematics, 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_transformer.updates;

import org.junit.Before;
import org.junit.Test;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.Stop;
import org.onebusaway.gtfs.services.GtfsRelationalDao;
import org.onebusaway.gtfs_transformer.AbstractTestSupport;

import java.io.File;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
* Document and test partial and fully accessible MTAStations.
*/
public class MTAStationAccessibilityStrategyTest extends AbstractTestSupport {

@Before
public void setup() throws Exception {
File stations_csv = new File(getClass().getResource(
"/org/onebusaway/gtfs_transformer/stations/stations.csv").toURI());
addModification("{\"op\": \"transform\", \"class\":\"org.onebusaway.gtfs_transformer.impl.MTAStationAccessibilityStrategy\", \"stations_csv\": \""+stations_csv+"\"}");
}

@Test
public void testStations() throws Exception {
_gtfs.putAgencies(1);
_gtfs.putNamedStops("R15,49 St", "A25,50 St", "233,Hoyt St", "626,86 St",
"R15N,49 St", "A25N,50 St", "233N,Hoyt St", "626N,86 St",
"R15S,49 St", "A25S,50 St", "233S,Hoyt St", "626S,86 St");
_gtfs.putRoutes(1);
_gtfs.putTrips(12, "r0", "sid0");
_gtfs.putStopTimes("t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11", "R15,A25,233,626,R15N,A25N,233N,626N,R15S,A25S,233S,626S");
_gtfs.putCalendars(1, "start_date=20120903", "end_date=20120916");

GtfsRelationalDao dao = transform();
assertStation(dao, "R15", 2, 1, 0); // 49 St (ADA=2, ADA NB=1, ADA SB=0)
assertStation(dao, "A25", 2, 0, 1); // 50 St (ADA=2, ADA NB=0, ADA SB=1
assertStation(dao, "233", 2, null, null); // Hoyt St (ADA=2, ADA NB=blank, ADA SB=blank)
assertStation(dao, "626", 2, 2, 0); // 86 St (ADA=2, ADA NB=2, ADA SB=0)
}

private void assertStation(GtfsRelationalDao dao, String stopId, int ada, Integer northBoundFlag, Integer southBoundFlag) {
Stop parentStop = dao.getStopForId(new AgencyAndId("a0", stopId));
assertNotNull(parentStop);
Stop nStop = dao.getStopForId(new AgencyAndId("a0", stopId+"N"));
assertNotNull(nStop);
Stop sStop = dao.getStopForId(new AgencyAndId("a0", stopId+"S"));
assertNotNull(sStop);

assertEquals("expecting ada flag to match wheelchairBoarding flag for stop " + parentStop.getId(),
ada, parentStop.getWheelchairBoarding());
if (northBoundFlag == null) {
assertEquals("expecting N/A wheelchairBoarding for northbound stop " + nStop,0, nStop.getWheelchairBoarding()); // default is 0
} else {
assertEquals("expecting northBoundFlag to match wheelchairBoarding flag for stop" + nStop, northBoundFlag.intValue(), nStop.getWheelchairBoarding());
}
if (southBoundFlag == null) {
assertEquals("expecting N/A wheelchairBoarding for southbound stop " + sStop,0, sStop.getWheelchairBoarding());
} else {
assertEquals("expecting southBoundFlag to match wheelchairBoarding flag for stop" + sStop, southBoundFlag.intValue(), sStop.getWheelchairBoarding());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Station ID,Complex ID,GTFS Stop ID,Division,Line,Stop Name,Borough,Daytime Routes,Structure,GTFS Latitude,GTFS Longitude,North Direction Label,South Direction Label,ADA,ADA Direction Notes,ADA NB,ADA SB,Capital Outage NB,Capital Outage SB
10,10,R15,BMT,Broadway - Brighton,49 St,M,N R W,Subway,40.759901,-73.984139,Uptown & Queens,Downtown & Brooklyn,2,Uptown & Queens,1,0,,
162,162,A25,IND,8th Av - Fulton St,50 St,M,C E,Subway,40.762456,-73.985984,Uptown - Queens,Downtown & Brooklyn,2,Downtown & Brooklyn only,0,1,,
336,336,233,IRT,Eastern Pky,Hoyt St,Bk,2 3,Subway,40.690545,-73.985065,Manhattan,Flatbush - New Lots,2,,,,,
397,397,626,IRT,Lexington Av,86 St,M,4 5 6,Subway,40.779492,-73.955589,Uptown & The Bronx,Downtown & Brooklyn,2,Uptown & The Bronx local only,2,0,,
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,36 @@ public void putStops(int numberOfRows, String... columns) {
putFile("stops.txt", b.build());
}

/**
* specify stop_id and stop_name, have stop generated with fake lat/lon
* @param rows
*/
public void putNamedStops(String...rows) {
int numberOfRows = rows.length;
List<String> stopIds = new ArrayList<>();
List<String> stopNames = new ArrayList<>();
List<String> stopLats = new ArrayList<String>();
List<String> stopLons = new ArrayList<String>();
TableBuilder b = new TableBuilder(numberOfRows);
for (String column : rows) {
String[] parts = column.split(",");
stopIds.add(parts[0]);
stopNames.add(parts[1]);
}
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_id", stopIds);
b.addColumnSpec("stop_name", stopNames);
b.addColumnSpec("stop_lat", stopLats);
b.addColumnSpec("stop_lon", stopLons);
putFile("stops.txt", b.build());
}

public void putDefaultStops() {
putDefaultAgencies();
putLines("stops.txt", "stop_id,stop_name,stop_lat,stop_lon",
Expand Down

0 comments on commit ef78c67

Please sign in to comment.