Skip to content

The "Seoul-Bus-Arrivals" service provides bus stop locations based on your current location and displays real-time bus arrival information for a selected stop on Google Maps.

License

Notifications You must be signed in to change notification settings

ahnshy/Seoul-Bus-Arrivals

Repository files navigation

Seoul Bus Arrivals (Next.js + MUI + Google Maps)

A responsive real‑time bus information web service built with Next.js (App Router), Material UI v6, and Google Maps JavaScript API.
Shows nearby bus stops, live arrival times, and a visual route line for each bus, with Light / Dark / Night themes and a dashboard-style UI.


✨ Features

  • Interactive map (Google Maps)

    • Default center is the user’s current browser location (via navigator.geolocation), with a “My location” button to re-center.
    • Users can drag the map; when dragging stops, the app fetches nearby bus stops around the new center.
    • Custom bus stop markers (red pins), with a distinct icon for the selected stop.
  • Nearby bus stops

    • Calls the Seoul Bus Station by Position API with current coordinates.
    • Displays the selected stop name, direction, and approximate distance (meters).
    • Automatically picks the nearest stop as the initial selection.
  • Realtime arrivals

    • For the selected stop, calls the Seoul Bus Arrivals by Station API.
    • Lists imminent buses with:
      • Route number
      • Destination / direction
      • Raw arrival message (e.g., “2분후[3번째 전]”)
    • Route number chips are color coded by route type:
      • Blue – Trunk (간선, type 3)
      • Green – Branch (지선, type 4)
      • Yellow – Circular (순환, type 5)
      • Red – Express / Metropolitan (광역, type 6)
    • Clicking a route chip draws the bus route path as a polyline on the map.
  • Route visualization

    • Uses a dedicated /api/route-path endpoint that wraps Seoul’s route-path API.
    • Draws a single red polyline for the currently selected route.
    • When a new route is selected, the previous polyline is removed from the map so only one route is visible at a time.
  • Theme modes

    • Light / Dark / Night themes with Night as the default.
    • Consistent palette for map container + right-hand side panel.
    • Theme toggle in the top-right app bar.
  • Responsive layout

    • On desktop: map on the left, realtime arrivals on the right.
    • On small screens: panels stack vertically (map on top, arrivals below).
    • Scrollable arrivals list with preserved header and GPS status indicator.

🧰 Tech Stack

Next.js App Router MUI Google%20Maps TypeScript React

  • Next.js 15 (App Router), React 18
  • Material UI v6 (@mui/material, @mui/icons-material, @emotion/*)
  • @react-google-maps/api
  • TypeScript

🌐 Live Demo


🔑 Environment

Create .env.local at the repo root and add the following keys:

# Google Maps JavaScript API
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=YOUR_GOOGLE_MAPS_JS_API_KEY

# Seoul Bus Open API (Decoding service key)
SEOUL_BUS_API_KEY=YOUR_SEOUL_BUS_DECODING_KEY

Important

  • For the Seoul Bus API, use the Decoding (원본) service key in .env.local; the app handles URL-encoding internally.
  • The Google Maps key must have Maps JavaScript API enabled.

🗄️ External APIs

This project integrates with the Seoul Bus Information System (BIS) open APIs:

  • Station by PositiongetStationByPos
    • Used by /api/stations to find stops near a given latitude/longitude.
    • The front-end passes user coordinates; the API returns a list of stops (arsId, stId, name, distance, GPS coordinates).
  • Arrivals by StationgetArrInfoByStation
    • Used by /api/arrivals to fetch arrivals for the selected stop (arsId).
    • The app parses arrmsg1 / arrmsg2, route name, and destination (adirection).
  • Route Path(a route-path endpoint, e.g., getRoutePath)
    • Wrapped by /api/route-path to get polylines for a given busRouteId.
    • The resulting array of { lat, lng } points is drawn as the red route line.

📁 Project Structure

app/
  layout.tsx               # Root layout, theme registry, metadata
  page.tsx                 # Main dashboard: map + realtime arrivals
  api/
    stations/route.ts      # GET /api/stations   → nearby bus stops
    arrivals/route.ts      # GET /api/arrivals   → realtime arrivals
    route-path/route.ts    # GET /api/route-path → bus route polyline
components/
  ThemeRegistry.tsx        # MUI theme provider + palette (Light/Dark/Night)
  ThemeToggle.tsx          # App bar toggle for theme modes
  MapPanel.tsx             # Core UI: GoogleMap, markers, arrivals panel
  types.ts                 # Shared TypeScript types (BusStop, BusArrival, etc.)
public/
  favicon.ico              # App favicon (bus icon on dark background)

🔌 API – Nearby Bus Stops

GET /api/stations

Wraps Seoul getStationByPos and returns normalized stop data for the front-end.

Query Parameters

Name Type Required Example Description
lat number 37.4979 Latitude (WGS84) of current map center
lng number 127.0276 Longitude (WGS84) of current map center

Sample Response

{
  "stops": [
    {
      "arsId": "22339",
      "stationId": "112000123",
      "name": "Gangnam Station",
      "direction": "Yeoksam Station",
      "distanceMeters": 79,
      "lat": 37.497942,
      "lng": 127.027621
    }
  ]
}

If the open API returns an error (e.g., header code not 0), the route responds with stops: [] and an error message, so the UI can fail gracefully.


🔌 API – Realtime Bus Arrivals

GET /api/arrivals

Wraps Seoul getArrInfoByStation and returns arrivals for a specific stop.

Query Parameters

Name Type Required Example Description
arsId string 22339 Stop unique number (정류소 고유번호)

Sample Response

{
  "arrivals": [
    {
      "routeId": "3411",
      "routeName": "3411",
      "routeType": 4,
      "destName": "Hanam Station",
      "predictMsg": "5분후[3번째 전]"
    }
  ]
}

The front-end:

  • Uses routeType to choose the chip color.
  • Sorts arrivals roughly by “soonest” using the first integer found in the message.

🔌 API – Bus Route Path

GET /api/route-path

Returns path coordinates for a specific bus route so the map can draw a polyline.

Query Parameters

Name Type Required Example Description
routeId string 3411 Seoul bus route ID

Sample Response

{
  "path": [
    { "lat": 37.49794, "lng": 127.02762 },
    { "lat": 37.50123, "lng": 127.03011 }
  ]
}

On the client side, the path is stored in state and mirrored into a single google.maps.Polyline instance.
Whenever the user clicks a different route:

  1. The current polyline is removed with setMap(null).
  2. A new polyline is created and attached to the map.
    This ensures there is never more than one route line displayed.

🧠 UX Notes

  • Right-hand panel shows:
    • GPS status chip (GPS OK / OFF / 오류 / 위치 확인 중…).
    • Selected stop name + direction + distance.
    • Scrollable Realtime arrivals list.
  • Clicking a bus stop marker:
    • Selects that stop, clears any existing route polyline, and loads arrivals.
  • Clicking a route chip:
    • Highlights the chip and draws the route line in red.
  • When geolocation is unavailable or denied:
    • GPS status switches to OFF or 오류, and the app falls back to a default center (Gangnam).
  • All heavy asynchronous calls (stations, arrivals, route-path) show spinners and user-friendly error messages.

🧩 Changelog (current build)

  1. Base layout using Next.js App Router and MUI with Night / Dark / Light theme support.
  2. Google Maps integration with custom red bus stop markers and selected-stop variant.
  3. Geolocation support: app centers on current browser location with a “My location” button.
  4. Nearby bus stops loader that reacts both to initial position and subsequent map drags.
  5. Realtime arrivals panel pulling live data from Seoul’s getArrInfoByStation API.
  6. Bus type color chips for Trunk / Branch / Circular / Express routes.
  7. Route polyline visualization, ensuring only the currently selected route is drawn.
  8. Added a custom favicon matching the Seoul Bus Arrivals theme.

🔗 Useful Commands

# install dependencies
npm -i

# start dev server (http://localhost:3000)
next dev

# type check & build production bundle
next build

📜 License

Internal demo for personal / internal projects.
Replace this section with your organization’s license terms if needed.

About

The "Seoul-Bus-Arrivals" service provides bus stop locations based on your current location and displays real-time bus arrival information for a selected stop on Google Maps.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages