Guides

Static Map Images

Generate static map images for thumbnails, social cards, and print

tileserver-rs includes a powerful static image API similar to Mapbox Static Images. Generate PNG, JPEG, or WebP images for:

  • Social media cards and Open Graph images
  • Email thumbnails
  • Print exports
  • Image placeholders before map loads
  • Server-side map rendering

Basic Usage

Center-Based Images

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

With Bearing and Pitch

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

Bounding Box Images

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

Retina/HiDPI Images

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]
Retina images are larger in file size but provide crisp maps on high-DPI displays like Retina MacBooks, iPhones, and modern Android devices.

Overlays

Path/Route Overlays

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 pairs

Multiple Paths

Separate 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

Marker Overlays

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)

Multiple Markers

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

Auto-Fit Mode

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

Auto-Fit Options

ParameterDescriptionDefault
paddingPadding ratio around content0.1 (10%)
maxzoomMaximum zoom level18
# 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

Use Cases

Open Graph / Social Cards

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" />

Email Thumbnails

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"
/>

Route Preview

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

Performance

Static image generation involves server-side rendering:

ScenarioTypical Time
Warm cache (tiles cached)~100-200ms
Cold cache (fetching tiles)~500-800ms
Large image (3000x2000)~1-2s
With overlays+50-100ms

Optimization Tips

  1. Use caching - Set up a CDN or reverse proxy cache for static images
  2. Limit dimensions - Larger images take longer to render
  3. Use WebP - Smaller file sizes than PNG/JPEG
  4. Pre-generate - For common images, generate ahead of time
# 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;
}

Error Handling

HTTP CodeMeaning
200Success
400Invalid parameters (bad coordinates, dimensions)
404Style not found
500Rendering 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

API Reference

See the full Static Image API Reference for all parameters and options.