Uber-style city demand heatmaps powered by PostGIS geospatial queries, aggregation pipelines, and pre-computed materialized views.
- Store ride coordinates – Pickup and dropoff lat/lng per trip
- Aggregate trips per region – Grid-based aggregation (500m cells)
- Demand heatmap – Pre-computed materialized view for fast reads
- Geospatial queries – PostGIS
ST_SquareGrid,ST_Intersects, GIST indexes
# 1. Start Postgres + PostGIS
docker compose up -d
# 2. Seed demo trips (NYC area)
go run ./cmd/seed
# 3. Start API server
go run ./cmd/server| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/heatmap?min_count=0 |
Demand heatmap (grid cells with trip counts) |
POST |
/api/v1/trips |
Create trip (pickup/dropoff coordinates) |
POST |
/api/v1/heatmap/refresh |
Re-run aggregation pipeline (refresh MV) |
GET |
/health |
Health check |
curl -X POST http://localhost:8080/api/v1/trips \
-H "Content-Type: application/json" \
-d '{"pickup_lng":-73.98,"pickup_lat":40.75,"dropoff_lng":-73.99,"dropoff_lat":40.76,"fare_amount":15.50,"passenger_count":2}'curl "http://localhost:8080/api/v1/heatmap?min_count=1"Response: { "cells": [...], "min_lng", "max_lng", "min_lat", "max_lat", "grid_m": 500 }
After adding trips, run:
curl -X POST http://localhost:8080/api/v1/heatmap/refresh| Env | Default |
|---|---|
DATABASE_URL |
postgres://triplytics:triplytics@localhost:5432/triplytics?sslmode=disable |
PORT |
8080 |
GRID_SIZE_M |
500 |
- PostGIS –
geography(POINT)for pickup/dropoff, spatial indexes - Materialized view
demand_heatmap– Grid cells withtrip_count,total_fare - Aggregation pipeline –
REFRESH MATERIALIZED VIEW CONCURRENTLY demand_heatmap