Skip to content

Commit

Permalink
Merge branch 'master' into 1663
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgamez authored Mar 11, 2024
2 parents 73b5c09 + 2f9fccd commit 5e6ea44
Show file tree
Hide file tree
Showing 15 changed files with 455 additions and 160 deletions.
1 change: 1 addition & 0 deletions .github/workflows/stg_web_svc_merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- master
workflow_dispatch:

env:
NODE_VERSION: "20"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class JsonReportSummary {
@SerializedName("counts")
private JsonReportCounts jsonReportCounts;

private List<String> gtfsComponents;
private List<String> gtfsFeatures;

public JsonReportSummary(
FeedMetadata feedMetadata,
Expand Down Expand Up @@ -89,7 +89,7 @@ public JsonReportSummary(
+ ", there will be missing data in the report.");
}

this.gtfsComponents =
this.gtfsFeatures =
feedMetadata.specFeatures == null
? null
: feedMetadata.specFeatures.entrySet().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public class FeedMetadata {
public ArrayList<AgencyMetadata> agencies = new ArrayList<>();
private ImmutableSortedSet<String> filenames;

// List of components that only require checking the presence of one record in the file.
private final List<Pair<String, String>> FILE_BASED_COMPONENTS =
// List of features that only require checking the presence of one record in the file.
private final List<Pair<String, String>> FILE_BASED_FEATURES =
List.of(
new Pair<>("Pathways (basic)", GtfsPathway.FILENAME),
new Pair<>("Transfers", GtfsTransfer.FILENAME),
Expand Down Expand Up @@ -136,26 +136,26 @@ private void loadSpecFeatures(GtfsFeedContainer feedContainer) {
}

private void loadSpecFeaturesBasedOnFilePresence(GtfsFeedContainer feedContainer) {
for (Pair<String, String> entry : FILE_BASED_COMPONENTS) {
for (Pair<String, String> entry : FILE_BASED_FEATURES) {
specFeatures.put(entry.getKey(), hasAtLeastOneRecordInFile(feedContainer, entry.getValue()));
}
}

private void loadSpecFeaturesBasedOnFieldPresence(GtfsFeedContainer feedContainer) {
loadRouteColorsComponent(feedContainer);
loadHeadsignsComponent(feedContainer);
loadWheelchairAccessibilityComponent(feedContainer);
loadTTSComponent(feedContainer);
loadBikeAllowanceComponent(feedContainer);
loadLocationTypesComponent(feedContainer);
loadTraversalTimeComponent(feedContainer);
loadPathwayDirectionsComponent(feedContainer);
loadPathwayExtraComponent(feedContainer);
loadRouteBasedFaresComponent(feedContainer);
loadContinuousStopsComponent(feedContainer);
loadRouteColorsFeature(feedContainer);
loadHeadsignsFeature(feedContainer);
loadWheelchairAccessibilityFeature(feedContainer);
loadTTSFeature(feedContainer);
loadBikeAllowanceFeature(feedContainer);
loadLocationTypesFeature(feedContainer);
loadTraversalTimeFeature(feedContainer);
loadPathwayDirectionsFeature(feedContainer);
loadPathwayExtraFeature(feedContainer);
loadRouteBasedFaresFeature(feedContainer);
loadContinuousStopsFeature(feedContainer);
}

private void loadContinuousStopsComponent(GtfsFeedContainer feedContainer) {
private void loadContinuousStopsFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Continuous Stops",
hasAtLeastOneRecordForFields(
Expand All @@ -176,7 +176,7 @@ private void loadContinuousStopsComponent(GtfsFeedContainer feedContainer) {
List.of((Function<GtfsStopTime, Boolean>) GtfsStopTime::hasContinuousPickup)));
}

private void loadRouteBasedFaresComponent(GtfsFeedContainer feedContainer) {
private void loadRouteBasedFaresFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Route-Based Fares",
hasAtLeastOneRecordForFields(
Expand All @@ -186,7 +186,7 @@ private void loadRouteBasedFaresComponent(GtfsFeedContainer feedContainer) {
|| hasAtLeastOneRecordInFile(feedContainer, GtfsNetwork.FILENAME));
}

private void loadPathwayDirectionsComponent(GtfsFeedContainer feedContainer) {
private void loadPathwayDirectionsFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Pathways Directions",
hasAtLeastOneRecordForFields(
Expand All @@ -197,7 +197,7 @@ private void loadPathwayDirectionsComponent(GtfsFeedContainer feedContainer) {
(Function<GtfsPathway, Boolean>) GtfsPathway::hasReversedSignpostedAs)));
}

private void loadPathwayExtraComponent(GtfsFeedContainer feedContainer) {
private void loadPathwayExtraFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Pathways (extra)",
hasAtLeastOneRecordForFields(
Expand All @@ -218,7 +218,7 @@ private void loadPathwayExtraComponent(GtfsFeedContainer feedContainer) {
List.of((Function<GtfsPathway, Boolean>) GtfsPathway::hasStairCount)));
}

private void loadTraversalTimeComponent(GtfsFeedContainer feedContainer) {
private void loadTraversalTimeFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Traversal Time",
hasAtLeastOneRecordForFields(
Expand All @@ -227,7 +227,7 @@ private void loadTraversalTimeComponent(GtfsFeedContainer feedContainer) {
List.of((Function<GtfsPathway, Boolean>) GtfsPathway::hasTraversalTime)));
}

private void loadLocationTypesComponent(GtfsFeedContainer feedContainer) {
private void loadLocationTypesFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Location Types",
hasAtLeastOneRecordForFields(
Expand All @@ -236,7 +236,7 @@ private void loadLocationTypesComponent(GtfsFeedContainer feedContainer) {
List.of((Function<GtfsStop, Boolean>) GtfsStop::hasLocationType)));
}

private void loadBikeAllowanceComponent(GtfsFeedContainer feedContainer) {
private void loadBikeAllowanceFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Bikes Allowance",
hasAtLeastOneRecordForFields(
Expand All @@ -245,7 +245,7 @@ private void loadBikeAllowanceComponent(GtfsFeedContainer feedContainer) {
List.of((Function<GtfsTrip, Boolean>) (GtfsTrip::hasBikesAllowed))));
}

private void loadTTSComponent(GtfsFeedContainer feedContainer) {
private void loadTTSFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Text-To-Speech",
hasAtLeastOneRecordForFields(
Expand All @@ -254,7 +254,7 @@ private void loadTTSComponent(GtfsFeedContainer feedContainer) {
List.of(((Function<GtfsStop, Boolean>) GtfsStop::hasTtsStopName))));
}

private void loadWheelchairAccessibilityComponent(GtfsFeedContainer feedContainer) {
private void loadWheelchairAccessibilityFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Wheelchair Accessibility",
hasAtLeastOneRecordForFields(
Expand All @@ -267,7 +267,7 @@ private void loadWheelchairAccessibilityComponent(GtfsFeedContainer feedContaine
List.of((Function<GtfsStop, Boolean>) GtfsStop::hasWheelchairBoarding)));
}

private void loadHeadsignsComponent(GtfsFeedContainer feedContainer) {
private void loadHeadsignsFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Headsigns",
hasAtLeastOneRecordForFields(
Expand All @@ -280,7 +280,7 @@ private void loadHeadsignsComponent(GtfsFeedContainer feedContainer) {
List.of((Function<GtfsStopTime, Boolean>) GtfsStopTime::hasStopHeadsign)));
}

private void loadRouteColorsComponent(GtfsFeedContainer feedContainer) {
private void loadRouteColorsFeature(GtfsFeedContainer feedContainer) {
specFeatures.put(
"Route Colors",
hasAtLeastOneRecordForFields(
Expand Down Expand Up @@ -319,17 +319,17 @@ private void loadFeedInfo(GtfsTableContainer<GtfsFeedInfo> feedTable) {
}

private boolean hasAtLeastOneRecordInFile(
GtfsFeedContainer feedContainer, String componentFilename) {
var table = feedContainer.getTableForFilename(componentFilename);
GtfsFeedContainer feedContainer, String featureFilename) {
var table = feedContainer.getTableForFilename(featureFilename);
return table.isPresent() && table.get().entityCount() > 0;
}

private <T extends GtfsEntity> boolean hasAtLeastOneRecordForFields(
GtfsFeedContainer feedContainer,
String componentFilename,
String featureFilename,
List<Function<T, Boolean>> conditions) {
return feedContainer
.getTableForFilename(componentFilename)
.getTableForFilename(featureFilename)
.map(
table ->
table.getEntities().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ public static void exportReport(
}
}
ZonedDateTime now = ZonedDateTime.now();
String date = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd 'at' HH:mm:ss z"));
String date = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"));
boolean is_different_date = !now.toLocalDate().equals(config.dateForValidation());

Gson gson = createGson(config.prettyJson());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,23 @@ private static long getRouteKey(GtfsRoute route) {
*
* <p>Example of bad data:
*
* <pre>
* | `route_id` | `route_short_name` | `route_long_name` |
* |------------ |-------------------- |------------------- |
* | route1 | U1 | Southern |
* | route2 | U1 | Southern |
* </pre>
* <table style="table-layout:auto; width:auto;">
* <tr>
* <th><code>route_id</code></th>
* <th><code>route_short_name</code></th>
* <th><code>route_long_name</code></th>
* </tr>
* <tr>
* <td>route1</td>
* <td>U1</td>
* <td>Southern</td>
* </tr>
* <tr>
* <td>route2</td>
* <td>U1</td>
* <td>Southern</td>
* </tr>
* </table>
*/
@GtfsValidationNotice(
severity = WARNING,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@
* <li>{@link DecreasingShapeDistanceNotice}
* <li>{@link EqualShapeDistanceSameCoordinatesNotice}
* <li>{@link EqualShapeDistanceDiffCoordinatesNotice}
* <li>{@link EqualShapeDistanceDiffCoordinatesDistanceBelowThresholdNotice}
* </ul>
*/
@GtfsValidator
public class ShapeIncreasingDistanceValidator extends FileValidator {

private final GtfsShapeTableContainer table;
private final double DISTANCE_THRESHOLD = 1.11;

@Inject
ShapeIncreasingDistanceValidator(GtfsShapeTableContainer table) {
Expand All @@ -72,8 +74,15 @@ public void validate(NoticeContainer noticeContainer) {
}
// equal shape_dist_traveled and different coordinates
if (!(curr.shapePtLon() == prev.shapePtLon() && curr.shapePtLat() == prev.shapePtLat())) {
noticeContainer.addValidationNotice(
new EqualShapeDistanceDiffCoordinatesNotice(prev, curr));
double distanceBetweenShapePoints =
getDistanceMeters(curr.shapePtLatLon(), prev.shapePtLatLon());
if (distanceBetweenShapePoints >= DISTANCE_THRESHOLD) {
noticeContainer.addValidationNotice(
new EqualShapeDistanceDiffCoordinatesNotice(prev, curr));
} else if (distanceBetweenShapePoints > 0) {
noticeContainer.addValidationNotice(
new EqualShapeDistanceDiffCoordinatesDistanceBelowThresholdNotice(prev, curr));
}
} else {
// equal shape_dist_traveled and same coordinates
noticeContainer.addValidationNotice(
Expand Down Expand Up @@ -177,7 +186,7 @@ static class EqualShapeDistanceSameCoordinatesNotice extends ValidationNotice {

/**
* Two consecutive points have equal `shape_dist_traveled` and different lat/lon coordinates in
* `shapes.txt`.
* `shapes.txt` and the distance between the two points is greater than the 1.11m.
*
* <p>When sorted by `shape.shape_pt_sequence`, the values for `shape_dist_traveled` must increase
* along a shape. Two consecutive points with equal values for `shape_dist_traveled` and different
Expand Down Expand Up @@ -209,8 +218,10 @@ static class EqualShapeDistanceDiffCoordinatesNotice extends ValidationNotice {
/** The previous record's `shapes.shape_pt_sequence`. */
private final int prevShapePtSequence;

// Actual distance traveled along the shape from the first shape point to the previous shape
/** point. */
/**
* Actual distance traveled along the shape from the first shape point to the previous shape
* point.
*/
private final double actualDistanceBetweenShapePoints;

EqualShapeDistanceDiffCoordinatesNotice(GtfsShape previous, GtfsShape current) {
Expand All @@ -225,4 +236,59 @@ static class EqualShapeDistanceDiffCoordinatesNotice extends ValidationNotice {
getDistanceMeters(current.shapePtLatLon(), previous.shapePtLatLon());
}
}

/**
* Two consecutive points have equal `shape_dist_traveled` and different lat/lon coordinates in
* `shapes.txt` and the distance between the two points is less than 1.11m.
*
* <p>When sorted by `shape.shape_pt_sequence`, the values for `shape_dist_traveled` must increase
* along a shape. Two consecutive points with equal values for `shape_dist_traveled` and small
* difference of coordinates (less than 1.11 m distance) result in a warning.
*/
@GtfsValidationNotice(
severity = WARNING,
files = @FileRefs({GtfsShapeSchema.class, GtfsStopSchema.class}))
static class EqualShapeDistanceDiffCoordinatesDistanceBelowThresholdNotice
extends ValidationNotice {

/** The id of the faulty shape. */
private final String shapeId;

/** The row number from `shapes.txt`. */
private final int csvRowNumber;

/** The faulty record's `shape_dist_traveled` value. */
private final double shapeDistTraveled;

/** The faulty record's `shapes.shape_pt_sequence`. */
private final int shapePtSequence;

/** The row number from `shapes.txt` of the previous shape point. */
private final long prevCsvRowNumber;

/** The previous shape point's `shape_dist_traveled` value. */
private final double prevShapeDistTraveled;

/** The previous record's `shapes.shape_pt_sequence`. */
private final int prevShapePtSequence;

/**
* Actual distance traveled along the shape from the first shape point to the previous shape
* point.
*/
private final double actualDistanceBetweenShapePoints;

EqualShapeDistanceDiffCoordinatesDistanceBelowThresholdNotice(
GtfsShape previous, GtfsShape current) {
this.shapeId = current.shapeId();
this.csvRowNumber = current.csvRowNumber();
this.shapeDistTraveled = current.shapeDistTraveled();
this.shapePtSequence = current.shapePtSequence();
this.prevCsvRowNumber = previous.csvRowNumber();
this.prevShapeDistTraveled = previous.shapeDistTraveled();
this.prevShapePtSequence = previous.shapePtSequence();
this.actualDistanceBetweenShapePoints =
getDistanceMeters(current.shapePtLatLon(), previous.shapePtLatLon());
}
}
}
Loading

0 comments on commit 5e6ea44

Please sign in to comment.