A geospatial REST API endpoint that efficiently finds the nearest bus stops in Singapore for any given coordinate. It leverages S2 geometry for fast, hierarchical spatial indexing and RocksDB as a high-performance embedded key–value store for low-latency lookups.
Refer to LEARNINGS.MD for lessons, challenges, and reflections from building this project.
Health check.
Response
{ "message": "pong" }Returns the 5 nearest bus stops to the given coordinates.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
lat |
float64 | Yes | Latitude |
lng |
float64 | Yes | Longitude |
Example
GET /bus-stops/nearest?lat=1.2968&lng=103.8525
Response
[
{
"BusStopCode": "01012",
"Description": "Hotel Grand Pacific",
"Latitude": 1.29684825487647,
"Longitude": 103.85253591654006,
"RoadName": "Victoria St",
"distance_m": 6.7
},
{
"BusStopCode": "01019",
"Description": "Bras Basah Cplx",
"Latitude": 1.29698951191332,
"Longitude": 103.85302201172507,
"RoadName": "Victoria St",
"distance_m": 61.7
},
{
"BusStopCode": "04179",
"Description": "Aft Bras Basah Stn Exit A",
"Latitude": 1.29647916306741,
"Longitude": 103.85147164487202,
"RoadName": "Bras Basah Rd",
"distance_m": 119.8
},
{
"BusStopCode": "01013",
"Description": "St. Joseph's Ch",
"Latitude": 1.29770970610083,
"Longitude": 103.8532247463225,
"RoadName": "Victoria St",
"distance_m": 129.3
},
{
"BusStopCode": "01029",
"Description": "Opp Natl Lib",
"Latitude": 1.2966729849642,
"Longitude": 103.85441422464267,
"RoadName": "Nth Bridge Rd",
"distance_m": 213.3
}
]Error responses
400 Bad Request— missing or invalidlat/lng404 Not Found— no bus stops found near the given location
- Go 1.25+
- RocksDB system libraries (installed automatically in the dev container):
librocksdb-dev libsnappy-dev liblz4-dev libzstd-dev
go mod tidyPopulate RocksDB with bus stop data from data/bus_stops.json:
go run seed.goOptional flag:
--input Path to JSON input file (default: ./data/bus_stops.json)
go run .Optional flags:
-db Path to RocksDB directory (default: ./data/rocksdb)
The server listens on port 8080.
go build ..
├── main.go # HTTP server and route handlers
├── nearest.go # Nearest bus stop search logic
├── seed.go # One-time DB seeding utility
├── config.go # Default path constants
├── data/
│ ├── bus_stops.json # Full Singapore bus stop dataset
│ ├── bus_stops_small.json # Small sample for testing
│ └── rocksdb/ # RocksDB data directory (generated)
└── internal/
├── config/ # Shared path constants
├── db/ # RocksDB wrapper and key definitions
├── geo/ # S2 cell utilities and distance calculation
└── models/ # BusStop data model
Bus stops are indexed in RocksDB under two key types:
stop:{BusStopCode}— full bus stop record (JSON)geo:{s2CellToken}:{BusStopCode}— spatial index entry
At query time, the API computes the S2 cell (level 14, ~600m edge) for the requested coordinates, scans that cell and its 4 edge neighbors, fetches matching stops, calculates geodesic distances, and returns the 5 closest results.
go test ./...