Skip to content

Commit

Permalink
Fix for conveyal#30
Browse files Browse the repository at this point in the history
  • Loading branch information
laidig committed Feb 21, 2017
1 parent 26a89f7 commit 3858dfc
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.onebusaway.gtfs.impl.GtfsRelationalDaoImpl;
import org.onebusaway.gtfs.impl.calendar.CalendarServiceDataFactoryImpl;
import org.onebusaway.gtfs.model.Agency;
Expand Down Expand Up @@ -155,6 +158,10 @@ public TreeMap<Calendar, ArrayList<AgencyAndId>> getServiceIdsForDates(){
return serviceIdsForDates;

}

public HashSet<AgencyAndId> getActiveServiceIdsOnly(){
return getServiceIdsForDates().values().stream().collect(HashSet::new, HashSet::addAll, HashSet::addAll);
}

public ArrayList<Calendar> getDatesWithNoTrips(){
ArrayList<Calendar> datesWithNoTrips = new ArrayList<Calendar>();
Expand Down Expand Up @@ -198,7 +205,7 @@ public String getTripDataForEveryDay(){
ServiceIdHelper helper = new ServiceIdHelper();
SimpleDateFormat df = new SimpleDateFormat("E, yyyy-MM-dd");
Calendar yesterday = Calendar.getInstance();
yesterday.add(Calendar.DAY_OF_MONTH, -1);;
yesterday.add(Calendar.DAY_OF_MONTH, -1);

TreeMap<Calendar, Integer> tc = getTripCountForDates();
for(Calendar d: tc.keySet()){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.onebusaway.gtfs.model.StopTime;
import org.onebusaway.gtfs.model.Trip;

import com.conveyal.gtfs.GtfsStatisticsServiceCalendarDatesTest;
import com.conveyal.gtfs.model.BlockInterval;
import com.conveyal.gtfs.model.DuplicateStops;
import com.conveyal.gtfs.model.InputOutOfRange;
Expand All @@ -42,6 +43,7 @@ public class GtfsValidationService {

private GtfsRelationalDaoImpl gtfsDao = null;
private GtfsStatisticsService statsService = null;
private CalendarDateVerificationService cdvs = null;

public GtfsValidationService(GtfsRelationalDaoImpl dao) {

Expand Down Expand Up @@ -109,14 +111,17 @@ public ValidationResult validateTrips() {

ValidationResult result = new ValidationResult();


// map stop time sequences to trip id

HashMap<String, ArrayList<StopTime>> tripStopTimes = new HashMap<String, ArrayList<StopTime>>(statsService.getStopTimesCount() *2);

HashSet<String> usedStopIds = new HashSet<String>(statsService.getStopCount() *2);

String tripId;

cdvs = new CalendarDateVerificationService(gtfsDao);
HashSet<AgencyAndId> activeServiceIds = cdvs.getActiveServiceIdsOnly();


for(StopTime stopTime : gtfsDao.getAllStopTimes()) {

Expand All @@ -133,12 +138,12 @@ public ValidationResult validateTrips() {

}

// create service calendar date map

// // create service calendar date map
//
//
@SuppressWarnings("deprecation")
int reasonableNumberOfDates = statsService.getNumberOfDays() *2;

HashMap<String, HashSet<Date>> serviceCalendarDates = new HashMap<String, HashSet<Date>>(reasonableNumberOfDates);
//TODO: factor out.
for(ServiceCalendar calendar : gtfsDao.getAllCalendars()) {
Expand Down Expand Up @@ -273,10 +278,11 @@ else if (exceptionType == 1) {

blockId = "";

if(trip.getBlockId() != null)
if(trip.getBlockId() != null){
blockId = trip.getBlockId();
}

if(!blockId.isEmpty()) {
if(!blockId.isEmpty() && activeServiceIds.contains(trip.getServiceId())) {

BlockInterval blockInterval = new BlockInterval();
blockInterval.setTrip(trip);
Expand Down Expand Up @@ -313,64 +319,67 @@ else if (exceptionType == 1) {
}
else
duplicateTripHash.put(tripKey, tripId);


}


// check for overlapping trips within block
for(Entry<String, ArrayList<BlockInterval>> blockIdset : blockIntervals.entrySet()) {

for(Entry<String, ArrayList<BlockInterval>> blockIdset : blockIntervals.entrySet()) {

blockId = blockIdset.getKey();
ArrayList<BlockInterval> intervals = blockIntervals.get(blockId);
blockId = blockIdset.getKey();
ArrayList<BlockInterval> intervals = blockIntervals.get(blockId);

Collections.sort(intervals, new BlockIntervalComparator());
Collections.sort(intervals, new BlockIntervalComparator());

int iOffset = 0;
for(BlockInterval i1 : intervals) {
for(BlockInterval i2 : intervals.subList(iOffset, intervals.size() - 1)) {
int iOffset = 0;
for(BlockInterval i1 : intervals) {
for(BlockInterval i2 : intervals.subList(iOffset, intervals.size() - 1)) {


String tripId1 = i1.getTrip().getId().toString();
String tripId2 = i2.getTrip().getId().toString();
String tripId1 = i1.getTrip().getId().toString();
String tripId2 = i2.getTrip().getId().toString();


if(!tripId1.equals(tripId2)) {
// if trips don't overlap, skip
if(i1.getLastStop().getDepartureTime() <= i2.getFirstStop().getArrivalTime()
|| i2.getLastStop().getDepartureTime() <= i1.getFirstStop().getArrivalTime())
continue;

// if trips have same service id they overlap
if(i1.getTrip().getServiceId().getId().equals(i2.getTrip().getServiceId().getId())) {
// but if they are already in the result set, ignore
if (!result.containsBoth(tripId1, tripId2, "trip")){
InvalidValue iv =
new InvalidValue("trip", "block_id", blockId, "OverlappingTripsInBlock", "Trip Ids " + tripId1 + " & " + tripId2 + " overlap and share block Id " + blockId , null, Priority.HIGH);
// not strictly correct; they could be on different routes
iv.route = i1.getTrip().getRoute();
result.add(iv);
}
}

else {
// if trips don't share service id check to see if service dates fall on the same days/day of week

for(Date d1 : serviceCalendarDates.get(i1.getTrip().getServiceId().getId())) {
if(!tripId1.equals(tripId2)) {
// if trips don't overlap, skip
if(i1.getLastStop().getDepartureTime() <= i2.getFirstStop().getArrivalTime()
|| i2.getLastStop().getDepartureTime() <= i1.getFirstStop().getArrivalTime())
continue;

if(serviceCalendarDates.get(i2.getTrip().getServiceId().getId()).contains(d1)) {
InvalidValue iv = new InvalidValue("trip", "block_id", blockId, "OverlappingTripsInBlock", "Trip Ids " + tripId1 + " & " + tripId2 + " overlap and share block Id " + blockId , null, Priority.HIGH);
// if trips have same service id they overlap
if(i1.getTrip().getServiceId().getId().equals(i2.getTrip().getServiceId().getId())) {
// but if they are already in the result set, ignore
if (!result.containsBoth(tripId1, tripId2, "trip")){
InvalidValue iv =
new InvalidValue("trip", "block_id", blockId, "OverlappingTripsInBlock", "Trip Ids " + tripId1 + " & " + tripId2 + " overlap and share block Id " + blockId , null, Priority.HIGH);
// not strictly correct; they could be on different routes
iv.route = i1.getTrip().getRoute();
result.add(iv);
break;
}
}

else {
// if trips don't share service id check to see if service dates fall on the same days/day of week

// try {

for(Date d1 : serviceCalendarDates.get(i1.getTrip().getServiceId().getId())) {

if(serviceCalendarDates.get(i2.getTrip().getServiceId().getId()).contains(d1)) {
InvalidValue iv = new InvalidValue("trip", "block_id", blockId, "OverlappingTripsInBlock", "Trip Ids " + tripId1 + " & " + tripId2 + " overlap and share block Id " + blockId , null, Priority.HIGH);
iv.route = i1.getTrip().getRoute();
result.add(iv);
break;
}
// }
//} catch (Exception e) {
//System.out.println("Could not find :"+ i1.getTrip().getServiceId().getId().toString());
}
}
}
}
}
}
}


// check for reversed trip shapes and add to result list
result.append(this.listReversedTripShapes());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.conveyal.gtfs;

import java.io.File;
import java.util.HashSet;

import org.junit.BeforeClass;
import org.junit.Test;
import org.onebusaway.csv_entities.exceptions.MissingRequiredFieldException;
import org.onebusaway.gtfs.impl.GtfsRelationalDaoImpl;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.serialization.GtfsReader;

import com.conveyal.gtfs.model.ValidationResult;
import com.conveyal.gtfs.service.CalendarDateVerificationService;
import com.conveyal.gtfs.service.GtfsValidationService;

import junit.framework.Assert;

public class ValidateTripsWasFailingBlocksTest extends UnitTestBaseUtil {
static GtfsValidationService gtfsValidation1 = null;
static GtfsRelationalDaoImpl gtfsMDao = null;
static MissingRequiredFieldException mrf = null;
static CalendarDateVerificationService cdvs = null;

@BeforeClass
public static void setUpClass() {
gtfsMDao = new GtfsRelationalDaoImpl();
GtfsReader gtfsReader1 = new GtfsReader();

try {

File gtfsFile1 = new File("src/test/resources/GTFS_MTABC_A7_SCS.zip");
gtfsReader1.setInputLocation(gtfsFile1);
gtfsReader1.setEntityStore(gtfsMDao);
gtfsReader1.run();

gtfsValidation1 = new GtfsValidationService(gtfsMDao);
cdvs = new CalendarDateVerificationService(gtfsMDao);


} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void validateTrips() {
ValidationResult result = gtfsValidation1.validateTrips();
Assert.assertEquals(0,result.invalidValues.size());
}

@Test
public void testListOfActiveServiceIds(){
Assert.assertTrue(cdvs.getActiveServiceIdsOnly().size() == 1);
}


}
Binary file not shown.

0 comments on commit 3858dfc

Please sign in to comment.