Skip to content

Show precipitation tiles with Leaflet map

API: Tiles API

This example demonstrates how to visualize Rainbow AI’s precipitation tile data on an interactive map using Leaflet. The setup consists of two parts:

  1. A simple Python-based tile proxy server (using FastAPI)

  2. A frontend HTML page rendering tiles via Leaflet

Description of image

Quick start

Install Backend Dependencies

Use pip to install the required Python packages:

Bash
pip install fastapi uvicorn requests

Prepare Files

Create the following two files in your working directory:

📄 server.py

service.py
import os
import requests
import uvicorn

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, Response

RAINBOW_API_TOKEN = os.getenv("RAINBOW_API_TOKEN")

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # You can restrict this later to specific domains
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/tiles/v1/snapshot")
def get_snapshot_timestamp_handler():
    response = requests.get(f"https://api.rainbow.ai/tiles/v1/snapshot?token={RAINBOW_API_TOKEN}")
    return JSONResponse(content=response.json())


@app.get("/tiles/v1/precip/{snapshot_timestamp}/{forecast_time}/{zoom}/{x}/{y}")
def get_tile_handler(snapshot_timestamp: int, forecast_time: int, zoom: int, x: int, y: int):
    url = f"https://api.rainbow.ai/tiles/v1/precip/{snapshot_timestamp}/{forecast_time}/{zoom}/{x}/{y}?token={RAINBOW_API_TOKEN}"
    response = requests.get(url, stream=True)
    return Response(content=response.content, media_type="image/png")


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

This FastAPI service proxies the tile and snapshot requests from Rainbow AI’s API and adds proper CORS headers for local development.

🌐 leaflet.html

leaflet.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Rainbow AI Precipitation Map</title>
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            width: 100%;
            height: 100vh;
        }
    </style>
</head>

<body>

    <div id="map"></div>

    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script>
        const BACKEND_URL = "http://localhost:8000"; // Replace with your actual backend URL

        async function getLatestSnapshotTimestamp() {
            const response = await fetch(`${BACKEND_URL}/tiles/v1/snapshot`);
            const data = await response.json();
            return data;
        }

        async function initializeMap() {
            const snapshot = await getLatestSnapshotTimestamp();
            const snapshotTimestamp = snapshot["snapshot"];
            const forecastTime = 0;

            const map = L.map('map').setView([50, 10], 5);

            // Base OpenStreetMap layer
            L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
                maxZoom: 19,
                attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
            }).addTo(map);

            // Custom precipitation tile layer
            const TILES_URL = `${BACKEND_URL}/tiles/v1/precip/${snapshotTimestamp}/${forecastTime}/{z}/{x}/{y}`;
            L.tileLayer(TILES_URL, {
                minZoom: 0,
                maxZoom: 7,
                tileSize: 256,
                attribution: 'Rainbow AI Precipitation Tiles',
                noWrap: true
            }).addTo(map);
        }

        // Initialize the map
        document.addEventListener("DOMContentLoaded", () => {
            initializeMap();
        });
    </script>

</body>

</html>

This HTML file displays the precipitation layer on a Leaflet map using the timestamped tile format.

Set Your Rainbow API Key

Export your API token as an environment variable:

Bash
export RAINBOW_API_TOKEN=<your-api-key>

Run the Tile Server

Bash
python server.py

Open leaflet.html. You will see a world map with precipitation tiles loaded dynamically from the Rainbow API, overlaid on top of OpenStreetMap base tiles.