Skip to content

Commit ced75d8

Browse files
feat(route-viewer): show realtime vehicle positions
relies on ibi-group/OpenTripPlanner#63 closes #440
1 parent 6e61767 commit ced75d8

File tree

5 files changed

+70
-3
lines changed

5 files changed

+70
-3
lines changed

lib/actions/api.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,27 @@ export function findStopsWithinBBox (params) {
704704

705705
export const clearStops = createAction('CLEAR_STOPS_OVERLAY')
706706

707+
// Realtime Vehcile positions query
708+
709+
const receivedVehiclePositions = createAction('REALTIME_VEHICLE_POSITIONS_RESPONSE')
710+
const receivedVehiclePositionsError = createAction('REALTIME_VEHICLE_POSITIONS_ERROR')
711+
712+
export function getVehiclePositionsForRoute (routeId) {
713+
return createQueryAction(
714+
`index/routes/${routeId}/vehicles`,
715+
receivedVehiclePositions,
716+
receivedVehiclePositionsError,
717+
{
718+
rewritePayload: (payload) => {
719+
return {
720+
routeId: routeId,
721+
vehicles: payload
722+
}
723+
}
724+
}
725+
)
726+
}
727+
707728
const throttledUrls = {}
708729

709730
function now () {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import TransitVehicleOverlay from '@opentripplanner/transit-vehicle-overlay'
2+
import { connect } from 'react-redux'
3+
4+
// connect to the redux store
5+
6+
const mapStateToProps = (state, ownProps) => {
7+
const viewedRoute = state.otp.ui.viewedRoute
8+
9+
let vehicleList = []
10+
11+
if (viewedRoute?.routeId) {
12+
vehicleList = state.otp.transitIndex?.routes?.[viewedRoute.routeId].vehicles
13+
if (viewedRoute.patternId) {
14+
vehicleList = vehicleList.filter(
15+
(vehicle) => vehicle.patternId === viewedRoute.patternId
16+
)
17+
}
18+
}
19+
return { vehicleList }
20+
}
21+
22+
const mapDispatchToProps = {}
23+
24+
export default connect(mapStateToProps, mapDispatchToProps)(TransitVehicleOverlay)

lib/components/map/default-map.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import BoundsUpdatingOverlay from './bounds-updating-overlay'
2020
import EndpointsOverlay from './connected-endpoints-overlay'
2121
import ParkAndRideOverlay from './connected-park-and-ride-overlay'
2222
import RouteViewerOverlay from './connected-route-viewer-overlay'
23+
import TransitVehicleOverlay from './connected-transit-vehicle-overlay'
2324
import StopViewerOverlay from './connected-stop-viewer-overlay'
2425
import StopsOverlay from './connected-stops-overlay'
2526
import TransitiveOverlay from './connected-transitive-overlay'
@@ -159,6 +160,7 @@ class DefaultMap extends Component {
159160
<BoundsUpdatingOverlay />
160161
<EndpointsOverlay />
161162
<RouteViewerOverlay />
163+
<TransitVehicleOverlay />
162164
<StopViewerOverlay />
163165
<TransitiveOverlay getTransitiveRouteLabel={getTransitiveRouteLabel} />
164166
<TripViewerOverlay />

lib/components/viewers/route-viewer.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import tinycolor from 'tinycolor2'
99

1010
import Icon from '../narrative/icon'
1111
import { setMainPanelContent, setViewedRoute } from '../../actions/ui'
12-
import { findRoutes, findRoute } from '../../actions/api'
12+
import { getVehiclePositionsForRoute, findRoutes, findRoute } from '../../actions/api'
1313
import { ComponentContext } from '../../util/contexts'
1414
import { getColorAndNameFromRoute, getModeFromRoute } from '../../util/viewer'
1515

@@ -33,6 +33,7 @@ class RouteViewer extends Component {
3333
render () {
3434
const {
3535
findRoute,
36+
getVehiclePositionsForRoute,
3637
hideBackButton,
3738
languageConfig,
3839
routes,
@@ -116,6 +117,7 @@ class RouteViewer extends Component {
116117
return (
117118
<RouteRow
118119
findRoute={findRoute}
120+
getVehiclePositionsForRoute={getVehiclePositionsForRoute}
119121
isActive={viewedRoute && viewedRoute.routeId === route.id}
120122
key={route.id}
121123
operator={operator}
@@ -195,15 +197,22 @@ const RouteNameElement = styled(Label)`
195197
class RouteRow extends PureComponent {
196198
static contextType = ComponentContext
197199

200+
componentDidMount = () => {
201+
const {getVehiclePositionsForRoute, isActive, route} = this.props
202+
if (isActive && route?.id) {
203+
getVehiclePositionsForRoute(route.id)
204+
}
205+
}
198206
_onClick = () => {
199-
const { findRoute, isActive, route, setViewedRoute } = this.props
207+
const { findRoute, getVehiclePositionsForRoute, isActive, route, setViewedRoute } = this.props
200208
if (isActive) {
201209
// Deselect current route if active.
202210
setViewedRoute({ patternId: null, routeId: null })
203211
} else {
204212
// Otherwise, set active and fetch route patterns.
205213
findRoute({ routeId: route.id })
206214
setViewedRoute({ routeId: route.id })
215+
getVehiclePositionsForRoute(route.id)
207216
}
208217
}
209218

@@ -266,6 +275,7 @@ const mapStateToProps = (state, ownProps) => {
266275
const mapDispatchToProps = {
267276
findRoute,
268277
findRoutes,
278+
getVehiclePositionsForRoute,
269279
setMainPanelContent,
270280
setViewedRoute
271281
}

lib/reducers/create-otp-reducer.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,16 @@ function createOtpReducer (config) {
752752
}
753753
}
754754
})
755+
case 'REALTIME_VEHICLE_POSITIONS_RESPONSE':
756+
return update(state, {
757+
transitIndex: {
758+
routes: {
759+
[action.payload.routeId]: {
760+
vehicles: { $set: action.payload.vehicles }
761+
}
762+
}
763+
}
764+
})
755765
case 'CLEAR_STOPS_OVERLAY':
756766
return update(state, {
757767
overlay: {
@@ -914,7 +924,7 @@ function createOtpReducer (config) {
914924
// Otherwise, overwrite only this route
915925
return update(state, {
916926
transitIndex: {
917-
routes: { [action.payload.id]: { $set: action.payload } }
927+
routes: { [action.payload.id]: { $merge: action.payload } }
918928
}
919929
})
920930
case 'FIND_PATTERNS_FOR_ROUTE_RESPONSE':

0 commit comments

Comments
 (0)