Skip to content

feat: add Next Departures map layer#1180

Draft
rm-hull wants to merge 8 commits intomainfrom
feat/next-departures
Draft

feat: add Next Departures map layer#1180
rm-hull wants to merge 8 commits intomainfrom
feat/next-departures

Conversation

@rm-hull
Copy link
Copy Markdown
Owner

@rm-hull rm-hull commented Apr 28, 2026

This commit introduces a new map layer that displays public transport
stops (bus and train) based on the current map viewport.

  • Adds NextDeparturesLayer to visualize transport stops using NaPTAN
    data.
  • Implements a custom useNaPTAN hook with react-query for
    efficient
    data fetching and caching.
  • Introduces a dynamic busStopWithBearing icon that renders an
    SVG-based arrow indicating the direction of the stop.
  • Provides stop details including name, locality, and bearing within
    map popups.
  • Includes unit tests for icon rotation logic.
sequenceDiagram
    participant M as Map (Leaflet)
    participant L as NextDeparturesLayer
    participant H as useNaPTAN Hook
    participant S as Next Departures Service
    participant A as API

    M->>L: Provides Bounds
    L->>H: Request data for bounds
    H->>S: fetchNaPTAN(bounds)
    S->>A: GET /v1/next-departures/search?bbox=...
    A-->>S: JSON NaPTAN Results
    S-->>H: SearchResponse
    H-->>L: results[]
    L->>M: Render Markers with custom Icons
Loading

rm-hull added 2 commits April 28, 2026 23:14
This commit introduces a new map layer that displays public transport
stops (bus and train) based on the current map viewport.

-   Adds `NextDeparturesLayer` to visualize transport stops using NaPTAN
    data.
-   Implements a custom `useNaPTAN` hook with `react-query` for
efficient
    data fetching and caching.
-   Introduces a dynamic `busStopWithBearing` icon that renders an
    SVG-based arrow indicating the direction of the stop.
-   Provides stop details including name, locality, and bearing within
    map popups.
-   Includes unit tests for icon rotation logic.

```mermaid
sequenceDiagram
    participant M as Map (Leaflet)
    participant L as NextDeparturesLayer
    participant H as useNaPTAN Hook
    participant S as Next Departures Service
    participant A as API

    M->>L: Provides Bounds
    L->>H: Request data for bounds
    H->>S: fetchNaPTAN(bounds)
    S->>A: GET /v1/next-departures/search?bbox=...
    A-->>S: JSON NaPTAN Results
    S-->>H: SearchResponse
    H-->>L: results[]
    L->>M: Render Markers with custom Icons
```
This change migrates the bus stop bearing display from a dynamic
`DivIcon` string generator to a reusable React component.

- Created `BearingIndicator` component using `react-leaflet` **Tooltip**
  to render direction arrows.
- Simplified `NextDeparturesLayer` by using the standard `busStop` icon
  wrapped in the new indicator.
- Added CSS to remove default **Tooltip** borders, backgrounds, and
  pointers for a clean SVG-only look.
- Updated unit tests to cover the new component and removed obsolete
  icon generation tests.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a 'Next Departures' map layer that displays public transport stops with bearing indicators. Key additions include the BearingIndicator component, a useNaPTAN hook for data fetching, and new Leaflet icons for bus and train stations. Review feedback focuses on improving consistency by renaming the 'direction' prop to 'bearing', exporting internal constants for unit tests, removing dead code, and aligning coordinate precision between the cache key and API service to optimize performance.

Comment thread src/components/map/BearingIndicator.tsx
Comment thread src/components/map/BearingIndicator.tsx
Comment thread src/components/map/layers/custom/NextDeparturesLayer.tsx
Comment thread src/icons/index.test.ts Outdated
Comment thread src/components/map/BearingIndicator.tsx
Comment on lines +39 to +47
{/* {data.departures.map((departure) => (
<Box key={departure.id} p={2} borderWidth={1} borderRadius="md">
<HStack justifyContent="space-between">
<Text fontWeight="bold">{departure.line_name}</Text>
<Text fontSize="sm" color="gray.500">{departure.destination_name}</Text>
</HStack>
<Text fontSize="sm" color="gray.500">{departure.expected_departure_time}</Text>
</Box>
))} */}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Remove this commented-out code block to maintain code cleanliness. If this functionality is intended for a future update, it should be tracked in a task or replaced with a TODO comment.

Comment thread src/hooks/useNaPTAN.ts

export function useNaPTAN(bounds: LatLngBounds) {
return useQuery<SearchResponse, AxiosError>({
queryKey: ["naptan", getBoundsKey(bounds, 4)],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The coordinate precision for the cache key (4 decimal places) does not match the default precision used in the fetchNaPTAN service (3 decimal places). This discrepancy can lead to redundant API calls for map bounds that resolve to the same rounded coordinates. It is recommended to align these values.

Suggested change
queryKey: ["naptan", getBoundsKey(bounds, 4)],
queryKey: ["naptan", getBoundsKey(bounds, 3)],

@rm-hull rm-hull marked this pull request as draft April 29, 2026 00:08
rm-hull added 4 commits April 29, 2026 21:02
Renames the `bearing` prop to `direction` to improve clarity and
consistency across the codebase. Removes `bearingAngles` from the
icon suite tests to reflect changes in the exported API.
Update the `queryFn` in the `useNaPTAN` hook to include the precision
level (**4**) when calling `fetchNaPTAN`, ensuring consistency with the
generated `queryKey`.
* 'main' of github.com:rm-hull/maps:
  chore: update yarn version
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 29, 2026

Coverage Report for CI Build 25179782139

Coverage increased (+0.4%) to 24.598%

Details

  • Coverage increased (+0.4%) from the base build.
  • Patch coverage: 29 uncovered changes across 4 files (12 of 41 lines covered, 29.27%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
src/services/nextDepartures/index.ts 13 0 0.0%
src/components/map/layers/custom/NextDeparturesLayer.tsx 12 0 0.0%
src/hooks/useNaPTAN.ts 2 0 0.0%
src/hooks/useNextDestination.ts 2 0 0.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1134
Covered Lines: 278
Line Coverage: 24.51%
Relevant Branches: 671
Covered Branches: 166
Branch Coverage: 24.74%
Branches in Coverage %: Yes
Coverage Strength: 2.68 hits per line

💛 - Coveralls

rm-hull added 2 commits April 29, 2026 21:17
- Add `NextDeparturesList` component to display real-time arrival info
  in a table format.
- Create `useNextDepartures` hook and service for fetching data by ATCO
  code.
- Refactor API types into a generic `Response<T>` interface.
- Update `dateReviver` regex to support ISO8601 strings with timezone
  offsets.

```mermaid
sequenceDiagram
    participant UI as NextDeparturesLayer
    participant List as NextDeparturesList
    participant Hook as useNextDepartures
    participant API as API Service

    UI->>List: Render with atcoCode
    List->>Hook: useNextDepartures(atcoCode)
    Hook->>API: GET /v1/next-departures/{atcoCode}
    API-->>Hook: return NextDeparture[]
    Hook-->>List: update data
    List->>UI: display departure Table
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants