forked from usdot-jpo-ode/jpo-cvmanager
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #130 from usdot-jpo-ode/add-new-reports
Add new reports
Showing
8 changed files
with
401 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
jpo-conflictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/models/ConnectionData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package us.dot.its.jpo.ode.api.models; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
import lombok.ToString; | ||
|
||
@Getter | ||
@Setter | ||
@ToString | ||
public class ConnectionData { | ||
private String connectionID; | ||
private int ingressLaneID; | ||
private int egressLaneID; | ||
private int eventCount; | ||
|
||
public ConnectionData(String connectionID, int ingressLaneID, int egressLaneID, int eventCount) { | ||
this.connectionID = connectionID; | ||
this.ingressLaneID = ingressLaneID; | ||
this.egressLaneID = egressLaneID; | ||
this.eventCount = eventCount; | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
...ictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/models/ConnectionOfTravelData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package us.dot.its.jpo.ode.api.models; | ||
|
||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.ArrayList; | ||
import java.util.stream.Collectors; | ||
import java.util.Arrays; | ||
|
||
import us.dot.its.jpo.geojsonconverter.pojos.geojson.LineString; | ||
import us.dot.its.jpo.geojsonconverter.pojos.geojson.connectinglanes.ConnectingLanesFeatureCollection; | ||
import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap; | ||
|
||
public class ConnectionOfTravelData { | ||
private List<ConnectionData> validConnections; | ||
private List<ConnectionData> invalidConnections; | ||
|
||
public ConnectionOfTravelData(List<ConnectionData> validConnections, List<ConnectionData> invalidConnections) { | ||
this.validConnections = validConnections; | ||
this.invalidConnections = invalidConnections; | ||
} | ||
|
||
public List<ConnectionData> getValidConnections() { | ||
return validConnections; | ||
} | ||
|
||
public List<ConnectionData> getInvalidConnections() { | ||
return invalidConnections; | ||
} | ||
|
||
public static ConnectionOfTravelData processConnectionOfTravelData(List<LaneConnectionCount> connectionCounts, ProcessedMap<LineString> mostRecentProcessedMap) { | ||
// Get the valid connections from the most recent processed map | ||
ConnectingLanesFeatureCollection<LineString> connectingLanesFeatureCollection = mostRecentProcessedMap.getConnectingLanesFeatureCollection(); | ||
Set<String> validConnectionIDs = Arrays.stream(connectingLanesFeatureCollection.getFeatures()) | ||
.map(feature -> feature.getId()) | ||
.collect(Collectors.toSet()); | ||
|
||
List<ConnectionData> validConnections = new ArrayList<>(); | ||
List<ConnectionData> invalidConnections = new ArrayList<>(); | ||
|
||
for (LaneConnectionCount count : connectionCounts) { | ||
String key = count.getIngressLaneID() + "-" + count.getEgressLaneID(); | ||
ConnectionData connectionData = new ConnectionData(key, count.getIngressLaneID(), count.getEgressLaneID(), count.getCount()); | ||
|
||
if (validConnectionIDs.contains(key)) { | ||
validConnections.add(connectionData); | ||
} else { | ||
invalidConnections.add(connectionData); | ||
} | ||
} | ||
|
||
return new ConnectionOfTravelData(validConnections, invalidConnections); | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
...izer-api/src/main/java/us/dot/its/jpo/ode/api/models/LaneDirectionOfTravelReportData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package us.dot.its.jpo.ode.api.models; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
import lombok.ToString; | ||
import us.dot.its.jpo.conflictmonitor.monitor.models.assessments.LaneDirectionOfTravelAssessment; | ||
import us.dot.its.jpo.conflictmonitor.monitor.models.assessments.LaneDirectionOfTravelAssessmentGroup; | ||
|
||
import java.time.Instant; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.*; | ||
import java.util.stream.Collectors; | ||
|
||
@Getter | ||
@Setter | ||
@ToString | ||
public class LaneDirectionOfTravelReportData { | ||
private long timestamp; | ||
private int laneID; | ||
private int segmentID; | ||
private double headingDelta; | ||
private double medianCenterlineDistance; | ||
|
||
public static List<LaneDirectionOfTravelReportData> processLaneDirectionOfTravelData(List<LaneDirectionOfTravelAssessment> assessments) { | ||
List<LaneDirectionOfTravelReportData> reportDataList = new ArrayList<>(); | ||
|
||
// Sort data by timestamp | ||
List<LaneDirectionOfTravelAssessment> sortedData = assessments.stream() | ||
.sorted(Comparator.comparing(LaneDirectionOfTravelAssessment::getTimestamp)) | ||
.collect(Collectors.toList()); | ||
|
||
// Group data by lane ID and segment ID | ||
Map<Integer, Map<Integer, List<LaneDirectionOfTravelReportData>>> groupedData = new HashMap<>(); | ||
for (LaneDirectionOfTravelAssessment assessment : sortedData) { | ||
long minute = Instant.ofEpochMilli(assessment.getTimestamp()).truncatedTo(ChronoUnit.MINUTES).toEpochMilli(); | ||
for (LaneDirectionOfTravelAssessmentGroup group : assessment.getLaneDirectionOfTravelAssessmentGroup()) { | ||
|
||
LaneDirectionOfTravelReportData reportData = new LaneDirectionOfTravelReportData(); | ||
reportData.setTimestamp(minute); | ||
reportData.setLaneID(group.getLaneID()); | ||
reportData.setSegmentID(group.getSegmentID()); | ||
reportData.setHeadingDelta(group.getMedianHeading() - group.getExpectedHeading()); | ||
reportData.setMedianCenterlineDistance(group.getMedianCenterlineDistance()); | ||
|
||
groupedData | ||
.computeIfAbsent(group.getLaneID(), k -> new HashMap<>()) | ||
.computeIfAbsent(group.getSegmentID(), k -> new ArrayList<>()) | ||
.add(reportData); | ||
} | ||
} | ||
|
||
// Aggregate data by minute for each lane ID and segment ID | ||
for (Map.Entry<Integer, Map<Integer, List<LaneDirectionOfTravelReportData>>> laneEntry : groupedData.entrySet()) { | ||
int laneID = laneEntry.getKey(); | ||
for (Map.Entry<Integer, List<LaneDirectionOfTravelReportData>> segmentEntry : laneEntry.getValue().entrySet()) { | ||
int segmentID = segmentEntry.getKey(); | ||
Map<Long, List<LaneDirectionOfTravelReportData>> aggregatedData = segmentEntry.getValue().stream() | ||
.collect(Collectors.groupingBy(LaneDirectionOfTravelReportData::getTimestamp)); | ||
|
||
for (Map.Entry<Long, List<LaneDirectionOfTravelReportData>> minuteEntry : aggregatedData.entrySet()) { | ||
long minute = minuteEntry.getKey(); | ||
List<LaneDirectionOfTravelReportData> minuteData = minuteEntry.getValue(); | ||
|
||
double averageHeadingDelta = minuteData.stream() | ||
.mapToDouble(LaneDirectionOfTravelReportData::getHeadingDelta) | ||
.average() | ||
.orElse(0.0); | ||
|
||
double averageCenterlineDistance = minuteData.stream() | ||
.mapToDouble(LaneDirectionOfTravelReportData::getMedianCenterlineDistance) | ||
.average() | ||
.orElse(0.0); | ||
|
||
LaneDirectionOfTravelReportData aggregatedReportData = new LaneDirectionOfTravelReportData(); | ||
aggregatedReportData.setTimestamp(minute); | ||
aggregatedReportData.setLaneID(laneID); | ||
aggregatedReportData.setSegmentID(segmentID); | ||
aggregatedReportData.setHeadingDelta(averageHeadingDelta); | ||
aggregatedReportData.setMedianCenterlineDistance(averageCenterlineDistance); | ||
|
||
reportDataList.add(aggregatedReportData); | ||
} | ||
} | ||
} | ||
|
||
return reportDataList; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
...visualizer-api/src/main/java/us/dot/its/jpo/ode/api/models/StopLinePassageReportData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package us.dot.its.jpo.ode.api.models; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.ArrayList; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
import lombok.ToString; | ||
import us.dot.its.jpo.conflictmonitor.monitor.models.events.StopLinePassageEvent; | ||
|
||
@Getter | ||
@Setter | ||
@ToString | ||
public class StopLinePassageReportData { | ||
private int signalGroup; | ||
private int totalEvents; | ||
private int redEvents; | ||
private int yellowEvents; | ||
private int greenEvents; | ||
private int darkEvents; | ||
|
||
public static List<StopLinePassageReportData> aggregateSignalStateEvents(List<StopLinePassageEvent> events) { | ||
Map<Integer, StopLinePassageReportData> reportDataMap = new HashMap<>(); | ||
|
||
for (StopLinePassageEvent event : events) { | ||
int signalGroup = event.getSignalGroup(); | ||
StopLinePassageReportData data = reportDataMap.getOrDefault(signalGroup, new StopLinePassageReportData()); | ||
data.setSignalGroup(signalGroup); | ||
data.setTotalEvents(data.getTotalEvents() + 1); | ||
|
||
switch(event.getEventState()) { | ||
case UNAVAILABLE: | ||
case DARK: | ||
data.setDarkEvents(data.getDarkEvents() + 1); | ||
break; | ||
case STOP_THEN_PROCEED: | ||
case STOP_AND_REMAIN: | ||
data.setRedEvents(data.getRedEvents() + 1); | ||
break; | ||
case PRE_MOVEMENT: | ||
case PERMISSIVE_MOVEMENT_ALLOWED: | ||
case PROTECTED_MOVEMENT_ALLOWED: | ||
data.setGreenEvents(data.getGreenEvents() + 1); | ||
break; | ||
case PERMISSIVE_CLEARANCE: | ||
case PROTECTED_CLEARANCE: | ||
case CAUTION_CONFLICTING_TRAFFIC: | ||
data.setYellowEvents(data.getYellowEvents() + 1); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
reportDataMap.put(signalGroup, data); | ||
} | ||
|
||
return new ArrayList<>(reportDataMap.values()); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...ictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/models/StopLineStopReportData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package us.dot.its.jpo.ode.api.models; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
import lombok.ToString; | ||
import us.dot.its.jpo.conflictmonitor.monitor.models.events.StopLineStopEvent; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.ArrayList; | ||
|
||
@Getter | ||
@Setter | ||
@ToString | ||
public class StopLineStopReportData { | ||
private int signalGroup; | ||
private int numberOfEvents; | ||
private double timeStoppedOnRed; | ||
private double timeStoppedOnYellow; | ||
private double timeStoppedOnGreen; | ||
private double timeStoppedOnDark; | ||
|
||
public static List<StopLineStopReportData> aggregateStopLineStopEvents(List<StopLineStopEvent> events) { | ||
Map<Integer, StopLineStopReportData> reportDataMap = new HashMap<>(); | ||
|
||
for (StopLineStopEvent event : events) { | ||
int signalGroup = event.getSignalGroup(); | ||
StopLineStopReportData data = reportDataMap.getOrDefault(signalGroup, new StopLineStopReportData()); | ||
data.setSignalGroup(signalGroup); | ||
data.setNumberOfEvents(data.getNumberOfEvents() + 1); | ||
data.setTimeStoppedOnRed(data.getTimeStoppedOnRed() + event.getTimeStoppedDuringRed()); | ||
data.setTimeStoppedOnYellow(data.getTimeStoppedOnYellow() + event.getTimeStoppedDuringYellow()); | ||
data.setTimeStoppedOnGreen(data.getTimeStoppedOnGreen() + event.getTimeStoppedDuringGreen()); | ||
data.setTimeStoppedOnDark(data.getTimeStoppedOnDark() + event.getTimeStoppedDuringDark()); | ||
reportDataMap.put(signalGroup, data); | ||
} | ||
|
||
return new ArrayList<>(reportDataMap.values()); | ||
} | ||
} |
171 changes: 111 additions & 60 deletions
171
jpo-conflictvisualizer-api/src/main/java/us/dot/its/jpo/ode/api/services/ReportService.java
Large diffs are not rendered by default.
Oops, something went wrong.