Skip to content

Commit

Permalink
experiment with showing all vehicles at once
Browse files Browse the repository at this point in the history
  • Loading branch information
miles-grant-ibigroup committed Oct 3, 2024
1 parent 8c85cb8 commit d6b44bb
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 28 deletions.
4 changes: 2 additions & 2 deletions lib/actions/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,6 @@ export const receivedVehiclePositionsError = createAction(
'REALTIME_VEHICLE_POSITIONS_ERROR'
)

export function getVehiclePositionsForRoute(routeId) {
return executeOTPAction('getVehiclePositionsForRoute', routeId)
export function getVehiclePositions(routeId) {
return executeOTPAction('getVehiclePositions', routeId)
}
4 changes: 2 additions & 2 deletions lib/actions/apiV1.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function findStopTimesForStop(params) {
}
}

const getVehiclePositionsForRoute = (routeId) =>
const getVehiclePositions = (routeId) =>
createQueryAction(
`index/routes/${routeId}/vehicles`,
receivedVehiclePositions,
Expand Down Expand Up @@ -166,7 +166,7 @@ export default {
findRoutes,
findStopTimesForStop,
findTrip,
getVehiclePositionsForRoute,
getVehiclePositions,
routingQuery,
vehicleRentalQuery
}
26 changes: 23 additions & 3 deletions lib/actions/apiV2.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,12 +606,12 @@ export const findStopTimesForStop = (params) =>
)
}

const getVehiclePositionsForRoute = (routeId) =>
const getVehiclePositions = (routeId) =>
function (dispatch, getState) {
return dispatch(
createGraphQLQueryAction(
`{
route(id: "${routeId}") {
route${routeId ? `(id: "${routeId}")` : 's'} {
patterns {
vehiclePositions {
vehicleId
Expand All @@ -629,6 +629,16 @@ const getVehiclePositionsForRoute = (routeId) =>
heading
lastUpdated
trip {
${
!routeId &&
`route {
shortName
longName
mode
color
textColor
}`
}
pattern {
id
}
Expand All @@ -643,6 +653,15 @@ const getVehiclePositionsForRoute = (routeId) =>
{
noThrottle: true,
rewritePayload: (payload) => {
if (payload.data?.routes) {
const vehicles = payload.data.routes.reduce((prev, cur) => {
return prev.concat(
cur.patterns.map((p) => p.vehiclePositions).flat()
)
}, [])

return { vehicles }
}
const vehicles = payload.data?.route?.patterns
.reduce((prev, cur) => {
return prev.concat(
Expand All @@ -664,6 +683,7 @@ const getVehiclePositionsForRoute = (routeId) =>
)
}, [])
.filter((vehicle) => !!vehicle)

return { routeId, vehicles }
}
}
Expand Down Expand Up @@ -1210,7 +1230,7 @@ export default {
findRoutes,
findStopTimesForStop,
findTrip,
getVehiclePositionsForRoute,
getVehiclePositions,
retrieveServiceTimeRangeIfNeeded,
routingQuery,
vehicleRentalQuery
Expand Down
54 changes: 54 additions & 0 deletions lib/components/map/connected-full-transit-vehicle-overlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { connect } from 'react-redux'

Check failure on line 1 in lib/components/map/connected-full-transit-vehicle-overlay.tsx

View workflow job for this annotation

GitHub Actions / test-build-release

Parameter 'obj' implicitly has an 'any' type.

Check failure on line 1 in lib/components/map/connected-full-transit-vehicle-overlay.tsx

View workflow job for this annotation

GitHub Actions / test-build-release

Parameter 'index' implicitly has an 'any' type.

Check failure on line 1 in lib/components/map/connected-full-transit-vehicle-overlay.tsx

View workflow job for this annotation

GitHub Actions / test-build-release

Parameter 'item' implicitly has an 'any' type.

Check failure on line 1 in lib/components/map/connected-full-transit-vehicle-overlay.tsx

View workflow job for this annotation

GitHub Actions / test-build-release

Parameter 'v' implicitly has an 'any' type.
import { injectIntl } from 'react-intl'
import React from 'react'
import TransitVehicleOverlay, {
Circle,
DefaultIconContainer,
RotatingCircle,
RouteNumberIcon,
withRouteColorBackground
} from '@opentripplanner/transit-vehicle-overlay'

import { DEFAULT_ROUTE_COLOR } from '../util/colors'

import { VehicleTooltip } from './connected-transit-vehicle-overlay'

const IconContainer = withRouteColorBackground(Circle)
// connect to the redux store
const mapStateToProps = (state: Record<string, any>) => {
const { viewedRoute } = state.otp.ui
// TODO: clever behavior for when route viewer is active

const vehicles = state.otp.transitIndex?.allVehicles
// TODO: CLEAN THIS UP
?.filter(
(obj, index) =>
state.otp.transitIndex?.allVehicles.findIndex(
(item) => item.vehicleId === obj.vehicleId
) === index
)
.map((v) => {
const { route } = v?.trip
v.routeType = route?.mode
v.routeColor =
route.color && !route.color.includes('#')
? '#' + route.color
: route?.color || DEFAULT_ROUTE_COLOR
// Try to populate this attribute, which is required for the vehicle popup to appear.
v.routeShortName = route?.shortName
v.routeLongName = v.routeLongName || route?.longName
v.textColor = route?.textColor
return v
})

// TODO: something funky is happening with the mode icon. Ferries are buses!
return {
IconContainer,
TooltipSlot: injectIntl(VehicleTooltip),
VehicleIcon: RouteNumberIcon,
vehicles
}
}

// @ts-expect-error state.js being typescripted will fix this error
export default injectIntl(connect(mapStateToProps)(TransitVehicleOverlay))
11 changes: 6 additions & 5 deletions lib/components/map/connected-transit-vehicle-overlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,21 @@
* 5) This overlay has a custom popup on vehicle hover
*/

import { connect } from 'react-redux'
import { FormattedMessage, FormattedNumber, injectIntl } from 'react-intl'
import React from 'react'
import TransitVehicleOverlay, {
Circle,
withCaret,
withRouteColorBackground
} from '@opentripplanner/transit-vehicle-overlay'

import { capitalizeFirst } from '../../util/ui'
import { connect } from 'react-redux'
import { DEFAULT_ROUTE_COLOR } from '../util/colors'
import { formatDuration } from '../util/formatted-duration'
import FormattedTransitVehicleStatus from '../util/formatted-transit-vehicle-status'

import React from 'react'

function VehicleTooltip(props) {
export function VehicleTooltip(props) {
const { intl, vehicle } = props

let vehicleLabel = vehicle?.label || vehicle?.vehicleId
Expand Down Expand Up @@ -65,7 +64,9 @@ function VehicleTooltip(props) {
{ id: 'common.time.durationAgo' },
{
duration: formatDuration(
Math.floor(Date.now() / 1000 - vehicle?.seconds),
Math.floor(
Date.now() / 1000 - (vehicle?.seconds || vehicle?.lastUpdated)
),
intl,
true
)
Expand Down
7 changes: 7 additions & 0 deletions lib/components/map/default-map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import { MainPanelContent } from '../../actions/ui-constants'
import { setLocation, setMapPopupLocationAndGeocode } from '../../actions/map'
import { setViewedStop } from '../../actions/ui'
import { updateOverlayVisibility } from '../../actions/config'
import VehiclePositionRetriever from '../viewers/vehicle-position-retriever'

import ElevationPointMarker from './elevation-point-marker'
import EndpointsOverlay from './connected-endpoints-overlay'
import FullTransitVehicleOverlay from './connected-full-transit-vehicle-overlay'
import GeoJsonLayer from './connected-geojson-layer'
import ItinSummaryOverlay from './itinerary-summary-overlay'
import NearbyViewDotOverlay from './nearby-view-dot-overlay'
Expand Down Expand Up @@ -409,6 +411,8 @@ class DefaultMap extends Component {
viewedRouteStops,
config.companies
)
case 'realtime-vehicles':
return <FullTransitVehicleOverlay {...namedLayerProps} />
default:
return null
}
Expand All @@ -419,6 +423,9 @@ class DefaultMap extends Component {
<NavigationControl
position={navigationControlPosition || 'bottom-right'}
/>
{overlays.map((o) => o.type).includes('realtime-vehicles') && (
<VehiclePositionRetriever fetchAll />
)}
</BaseMap>
</MapContainer>
)
Expand Down
20 changes: 11 additions & 9 deletions lib/components/viewers/vehicle-position-retriever.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { useCallback, useEffect, useState } from 'react'
import * as apiActions from '../../actions/api'

interface Props {
getVehiclePositionsForRoute: (id: string) => void
fetchAll?: boolean
getVehiclePositions: (id?: string) => void
refreshSeconds: number
routeId?: string
}
Expand All @@ -13,21 +14,22 @@ interface Props {
* Non-visual component that retrieves vehicle positions for the given route.
*/
const VehiclePositionRetriever = ({
getVehiclePositionsForRoute,
fetchAll,
getVehiclePositions,
refreshSeconds,
routeId
}: Props) => {
const [refreshTimer, setRefreshTimer] = useState<NodeJS.Timeout | null>(null)

const refreshVehiclePositions = useCallback(() => {
if (routeId) {
getVehiclePositionsForRoute(routeId)
if (routeId || fetchAll) {
getVehiclePositions(routeId)
}
}, [routeId, getVehiclePositionsForRoute])
}, [routeId, getVehiclePositions, fetchAll])

useEffect(() => {
// Fetch vehicle positions when initially mounting component and a route id is available.
if (routeId) {
if (routeId || fetchAll) {
refreshVehiclePositions()

if (!refreshTimer) {
Expand All @@ -45,7 +47,7 @@ const VehiclePositionRetriever = ({
setRefreshTimer(null)
}
}
}, [routeId, refreshVehiclePositions, refreshTimer, refreshSeconds])
}, [routeId, refreshVehiclePositions, refreshTimer, refreshSeconds, fetchAll])

// Component renders nothing.
return null
Expand All @@ -55,13 +57,13 @@ const VehiclePositionRetriever = ({
const mapStateToProps = (state: any) => {
return {
refreshSeconds:
state.otp.config.routeViewer?.vehiclePositionRefreshSeconds || 30,
state.otp.config.routeViewer?.vehiclePositionRefreshSeconds || 10,
routeId: state.otp.ui.viewedRoute?.routeId
}
}

const mapDispatchToProps = {
getVehiclePositionsForRoute: apiActions.getVehiclePositionsForRoute
getVehiclePositions: apiActions.getVehiclePositions
}

export default connect(
Expand Down
20 changes: 13 additions & 7 deletions lib/reducers/create-otp-reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,15 +690,21 @@ function createOtpReducer(config) {
case 'REALTIME_VEHICLE_POSITIONS_RESPONSE':
if (!action.payload?.vehicles) return state

return update(state, {
transitIndex: {
routes: {
[action.payload.routeId]: {
vehicles: { $set: action.payload.vehicles }
if (action.payload?.routeId) {
return update(state, {
transitIndex: {
routes: {
[action.payload.routeId]: {
vehicles: { $set: action.payload.vehicles }
}
}
}
}
})
})
} else {
return update(state, {
transitIndex: { allVehicles: { $set: action.payload.vehicles } }
})
}
case 'CLEAR_STOPS_OVERLAY':
return update(state, {
overlay: {
Expand Down

0 comments on commit d6b44bb

Please sign in to comment.