Skip to content

๐ŸšŒ Real-time visualization of STCP bus positions in Porto on an interactive map. Built with React, TypeScript, and MapLibre GL JS.

Notifications You must be signed in to change notification settings

davidrocha9/linha-viva

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

19 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Linha Viva Porto

Linha Viva Porto is a web app that visualizes the live positions of STCP buses in Porto on an interactive map.

It provides a smooth, GPU-accelerated, real-time view of buses in motion with route details, stop information, and bus tracking capabilities.


โœจ Features

Map & Visualization

  • Live bus positions - Real-time visualization of all STCP buses on an interactive map
  • Smooth animations - GPU-accelerated animations for hundreds of buses using WebGL
  • Multiple map styles - Switch between different map styles (Voyager, Positron, Dark Matter)
  • Interactive bus selection - Click any bus to view detailed information
  • Visual focus - Selected buses remain at full opacity while others fade out
  • Route visualization - View route paths and stops when selecting a route or bus

Route Management

  • Route dashboard - Browse all available routes with filtering and search
  • Route filtering - Filter buses by specific route lines
  • Route details - View complete route information including:
    • Route path visualization
    • All stops along the route
    • Active buses on the route
    • Direction switching (Outbound/Inbound)
    • Stop timeline with progression tracking

Bus Tracking

  • Bus selection - Select individual buses to track their position
  • Active buses list - See all active buses for a selected route and direction
  • Direction detection - Automatically detect bus direction based on position
  • Route progression - Track which stops a bus has passed and which are next

User Interface

  • Search functionality - Search routes by name or number
  • Network statistics - View total routes and active buses count
  • Collapsible dashboard - Expandable sidebar for route management
  • Responsive design - Optimized for various screen sizes

๐Ÿง  Data Sources

Static Data (GTFS)

Preprocessed GTFS data stored in the repository:

  • Routes and route metadata
  • Stops and stop locations
  • Trips and trip schedules
  • Route shapes and paths
  • Calendar and service dates

Location: public/data/stcp/

Live Data (API)

Urban Platform โ€“ Bus Location (STCP)
OpenData Porto

  • Real-time bus positions (latitude, longitude, bearing)
  • Bus line information
  • Periodic updates (~10โ€“15s intervals)

๐Ÿ—บ๏ธ Tech Stack

Runtime & Tooling

  • Bun - Fast JavaScript runtime, package manager, and bundler
  • Vite - Build tool and dev server (bundled with Bun)

Frontend Framework

  • React 18 - UI library
  • TypeScript - Type-safe development
  • TailwindCSS - Utility-first CSS framework

Mapping & Visualization

  • MapLibre GL JS - Open-source map rendering library
  • WebGL - GPU-accelerated rendering
  • GeoJSON - Geographic data format

State Management

  • React Context API - Global state management
  • Custom hooks for data fetching and map interactions

Data Processing

  • GTFS parsing - Client-side GTFS data processing
  • CSV Workers - Web Workers for parsing large GTFS files
  • Geospatial calculations - Distance and direction calculations

๐Ÿ—๏ธ Architecture

Browser (Client-Side)
โ”œโ”€โ”€ Static GTFS Data (public/data/stcp/)
โ”‚   โ”œโ”€โ”€ routes.txt
โ”‚   โ”œโ”€โ”€ stops.txt
โ”‚   โ”œโ”€โ”€ trips.txt
โ”‚   โ”œโ”€โ”€ shapes.txt
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ Periodic API Fetch โ†’ STCP Live Bus Positions
โ”œโ”€โ”€ React Components
โ”‚   โ”œโ”€โ”€ MapContainer (MapLibre GL)
โ”‚   โ”œโ”€โ”€ RouteDashboard (Route list & filtering)
โ”‚   โ”œโ”€โ”€ RouteDetail (Route information & stops)
โ”‚   โ””โ”€โ”€ NetworkStats (Live statistics)
โ”œโ”€โ”€ Context Providers
โ”‚   โ”œโ”€โ”€ AppContext (Global state)
โ”‚   โ””โ”€โ”€ RouteDetailContext (Route-specific state)
โ”œโ”€โ”€ Custom Hooks
โ”‚   โ”œโ”€โ”€ useBusPositions (Live bus data)
โ”‚   โ”œโ”€โ”€ useBusLayer (Map bus rendering)
โ”‚   โ”œโ”€โ”€ useRouteLayer (Route path rendering)
โ”‚   โ””โ”€โ”€ useRouteDetailData (Route information)
โ””โ”€โ”€ Services
    โ”œโ”€โ”€ busService (API integration)
    โ””โ”€โ”€ gtfsService (GTFS data parsing)

All logic runs client-side - No backend, no database, no authentication.


๐Ÿš€ Getting Started

Prerequisites

  • Bun (latest version)

Installation

  1. Clone the repository

    git clone <repository-url>
    cd linha-viva
  2. Install dependencies

    bun install
  3. Run development server

    bun dev
  4. Open in browser Navigate to the URL shown in your terminal (typically http://localhost:5173)

Building for Production

bun run build

The production build will be in the dist/ directory.


๐ŸŽž๏ธ Animation Strategy

Bus movement is animated smoothly using:

  1. Periodic API fetching - Fetch live positions at fixed intervals (~10-15s)
  2. Position interpolation - Store previous and next coordinates per vehicle
  3. RequestAnimationFrame - Interpolate positions between API updates
  4. GeoJSON updates - Update map source on each animation frame
  5. GPU acceleration - WebGL rendering handles hundreds of moving vehicles efficiently

This approach:

  • โœ… Avoids marker "teleporting"
  • โœ… Provides smooth, continuous movement
  • โœ… Scales well to hundreds of buses
  • โœ… Maintains 60fps performance

๐Ÿ“ Project Structure

src/
โ”œโ”€โ”€ components/
โ”‚   โ”œโ”€โ”€ dashboard/          # Dashboard UI components
โ”‚   โ”‚   โ”œโ”€โ”€ RouteDashboard.tsx
โ”‚   โ”‚   โ”œโ”€โ”€ RouteDetail/    # Route detail components
โ”‚   โ”‚   โ”œโ”€โ”€ FloatingSearch.tsx
โ”‚   โ”‚   โ””โ”€โ”€ NetworkStats.tsx
โ”‚   โ””โ”€โ”€ map/                # Map-related components
โ”‚       โ”œโ”€โ”€ MapContainer.tsx
โ”‚       โ””โ”€โ”€ MapZoomControls.tsx
โ”œโ”€โ”€ context/                # React Context providers
โ”‚   โ”œโ”€โ”€ AppContext.tsx
โ”‚   โ””โ”€โ”€ RouteDetailContext.tsx
โ”œโ”€โ”€ hooks/                  # Custom React hooks
โ”‚   โ”œโ”€โ”€ dashboard/          # Dashboard-related hooks
โ”‚   โ”œโ”€โ”€ map/               # Map-related hooks
โ”‚   โ””โ”€โ”€ useBusPositions.ts
โ”œโ”€โ”€ services/              # Data services
โ”‚   โ”œโ”€โ”€ busService.ts      # STCP API integration
โ”‚   โ”œโ”€โ”€ gtfsService.ts     # GTFS data parsing
โ”‚   โ””โ”€โ”€ csvWorker.ts       # CSV parsing worker
โ”œโ”€โ”€ types/                 # TypeScript type definitions
โ”œโ”€โ”€ constants/             # App constants
โ””โ”€โ”€ lib/                   # Utility functions

โš ๏ธ Notes & Limitations

  • API dependency - App depends on the public STCP API; avoid aggressive polling
  • Data quality - GPS accuracy and update frequency depend on STCP's data quality
  • Browser compatibility - Requires modern browser with WebGL support
  • GTFS data - Static GTFS files are included in the repo for offline reference
  • No delay calculations - Real-time delay/lateness calculations are not currently implemented

๐Ÿ”ฎ Future Enhancements

Potential features for future development:

  • Real-time delay and lateness calculations
  • Backend caching layer for improved performance
  • Historical data analysis
  • User preferences and saved routes
  • Mobile app version
  • Offline mode with cached data

๐Ÿ“œ License

This project is open-source and uses public open data.
Check the original datasets for their respective licenses.


๐Ÿ™Œ Acknowledgements

  • STCP โ€“ Sociedade de Transportes Colectivos do Porto
  • Porto Digital โ€“ Open Data Portal
  • MapLibre โ€“ Open-source mapping library
  • OpenStreetMap โ€“ Map data provider

About

๐ŸšŒ Real-time visualization of STCP bus positions in Porto on an interactive map. Built with React, TypeScript, and MapLibre GL JS.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages