tileserver-rs includes a powerful static image API similar to Mapbox Static Images. Generate PNG, JPEG, or WebP images for:
Specify center coordinates and zoom level:
GET /styles/{style}/static/{lon},{lat},{zoom}/{width}x{height}.{format}
# San Francisco at zoom 12, 800x600 PNG
curl "http://localhost:8080/styles/bright/static/-122.4194,37.7749,12/800x600.png" > sf.png
# Tokyo at zoom 14, 1200x630 JPEG (Open Graph size)
curl "http://localhost:8080/styles/bright/static/139.6917,35.6895,14/1200x630.jpeg" > tokyo.jpg
# WebP format (smaller file size)
curl "http://localhost:8080/styles/bright/static/2.3522,48.8566,13/800x600.webp" > paris.webp
Add rotation (bearing) and tilt (pitch) for 3D-style views:
GET /styles/{style}/static/{lon},{lat},{zoom}@{bearing},{pitch}/{width}x{height}.{format}
# 45-degree rotation, 60-degree tilt
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,15@45,60/800x600.png" > tilted.png
# North-up (0 bearing), slight tilt
curl "http://localhost:8080/styles/bright/static/11.255,43.77,16@0,30/800x600.png" > florence.png
Fit a specific geographic area:
GET /styles/{style}/static/{minLon},{minLat},{maxLon},{maxLat}/{width}x{height}.{format}
# Bay Area bounding box
curl "http://localhost:8080/styles/bright/static/-122.6,37.4,-121.8,37.9/1024x768.png" > bay-area.png
# Manhattan
curl "http://localhost:8080/styles/bright/static/-74.02,40.7,-73.97,40.8/800x1000.png" > manhattan.png
Add @2x or @3x for high-resolution displays:
# 2x resolution (1600x1200 actual pixels for 800x600 display)
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,12/[email protected]" > [email protected]
# 3x resolution
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,12/[email protected]" > [email protected]
Draw lines on the map using the path query parameter:
?path=path-{strokeWidth}+{color}({lon1},{lat1}|{lon2},{lat2}|...)
# Red route, 5px wide
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,12/800x600.png?\
path=path-5+ff0000(-122.42,37.78|-122.41,37.79|-122.40,37.78)" > route.png
# Blue dashed path
curl "http://localhost:8080/styles/bright/static/auto/800x600.png?\
path=path-3+0066ff(-122.5,37.7|-122.4,37.8|-122.3,37.75)" > blue-route.png
Path format:
path-5 = 5 pixel stroke width+ff0000 = red color (hex, 3 or 6 digits)(coords) = pipe-separated lon,lat pairsSeparate multiple paths with ~:
curl "http://localhost:8080/styles/bright/static/auto/800x600.png?\
path=path-4+ff0000(-122.4,37.8|-122.5,37.85)~path-4+0000ff(-122.45,37.78|-122.35,37.82)" > multi-route.png
Add markers using the marker query parameter:
?marker=pin-{size}[-{label}]+{color}({lon},{lat})
# Small red pin
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,14/800x600.png?\
marker=pin-s+ff0000(-122.4,37.8)" > marker.png
# Medium blue pin with label "A"
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,14/800x600.png?\
marker=pin-m-A+0066ff(-122.4,37.8)" > labeled-marker.png
# Large green pin
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,14/800x600.png?\
marker=pin-l+00ff00(-122.4,37.8)" > large-marker.png
Marker sizes:
pin-s = small (20x50 pixels)pin-m = medium (30x70 pixels)pin-l = large (40x100 pixels)curl "http://localhost:8080/styles/bright/static/auto/800x600.png?\
marker=pin-s-A+ff0000(-122.42,37.78)~pin-s-B+00ff00(-122.40,37.79)~pin-s-C+0000ff(-122.41,37.77)" > abc-markers.png
Use auto to automatically fit the map to your overlays:
# Fit to route
curl "http://localhost:8080/styles/bright/static/auto/800x600.png?\
path=path-5+ff0000(-122.5,37.7|-122.4,37.8|-122.3,37.9)" > auto-route.png
# Fit to markers
curl "http://localhost:8080/styles/bright/static/auto/800x600.png?\
marker=pin-s+ff0000(-122.5,37.7)~pin-s+ff0000(-122.3,37.9)" > auto-markers.png
| Parameter | Description | Default |
|---|---|---|
padding | Padding ratio around content | 0.1 (10%) |
maxzoom | Maximum zoom level | 18 |
# More padding (20%)
curl "http://localhost:8080/styles/bright/static/auto/800x600.png?\
path=path-5+ff0000(-122.5,37.7|-122.3,37.9)&padding=0.2" > padded.png
# Limit max zoom to 14
curl "http://localhost:8080/styles/bright/static/auto/800x600.png?\
marker=pin-s+ff0000(-122.4,37.8)&maxzoom=14" > limited-zoom.png
Generate images for social media sharing (1200x630 is the recommended OG size):
# Generate OG image for a location page
curl "http://localhost:8080/styles/bright/static/${LON},${LAT},14/1200x630.png" > og-image.png
<meta property="og:image" content="https://yourdomain.com/og-image.png" />
Static images work in all email clients (unlike interactive maps):
<img
src="https://tiles.yourdomain.com/styles/bright/static/-122.4,37.8,12/400x300.png"
alt="Map of San Francisco"
/>
Show a route preview before loading the full interactive map:
// Generate static image URL
const routeCoords = route.map(c => `${c[0]},${c[1]}`).join('|');
const staticUrl = `http://localhost:8080/styles/bright/static/auto/800x400.png?path=path-4+3388ff(${routeCoords})`;
// Show as placeholder
document.getElementById('map-placeholder').src = staticUrl;
Generate high-resolution images for printing:
# A4 landscape at 300 DPI (3508x2480 pixels)
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,12/3508x2480.png" > print-a4.png
# Use @2x for even higher quality
curl "http://localhost:8080/styles/bright/static/-122.4,37.8,12/[email protected]" > print-a4-hd.png
Static image generation involves server-side rendering:
| Scenario | Typical Time |
|---|---|
| Warm cache (tiles cached) | ~100-200ms |
| Cold cache (fetching tiles) | ~500-800ms |
| Large image (3000x2000) | ~1-2s |
| With overlays | +50-100ms |
# nginx caching example
location ~ ^/styles/.*/static/ {
proxy_pass http://tileserver:8080;
proxy_cache static_maps;
proxy_cache_valid 200 1h;
proxy_cache_key $uri$is_args$args;
}
| HTTP Code | Meaning |
|---|---|
200 | Success |
400 | Invalid parameters (bad coordinates, dimensions) |
404 | Style not found |
500 | Rendering error |
Common errors:
# Invalid coordinates
curl "http://localhost:8080/styles/bright/static/invalid,coords,12/800x600.png"
# Returns 400 Bad Request
# Style doesn't exist
curl "http://localhost:8080/styles/nonexistent/static/-122.4,37.8,12/800x600.png"
# Returns 404 Not Found
See the full Static Image API Reference for all parameters and options.