Quick start: flutter_map (raster)
The shortest path in a Flutter app: show PNG tiles drawn from Updraft's pilot eye style with flutter_map. If your app uses raster tiles from OpenStreetMap or another provider today, switching is an address and attribution change.
1. Dependencies
flutter pub add updraft_maps flutter_map:8.3.2 latlong2:0.10.1 url_launcher:6.3.3
updraft_maps is Updraft's client package: tile address, key header, zoom limits, cache and attribution line in one call (updraftTileLayer, UpdraftAttribution). url_launcher only opens the rules page when the attribution line is tapped.
2. Map
// Updraft quick start 2: flutter_map 8 with Updraft raster tiles (PNG, 256 px; @2x on dense
// screens), through the updraft_maps package.
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:updraft_maps/flutter_map.dart';
import 'package:url_launcher/url_launcher.dart';
/// Updraft tile server root (another one, e.g. staging: --dart-define=UPDRAFT_TILES=https://...).
const updraftTiles = String.fromEnvironment(
'UPDRAFT_TILES',
defaultValue: defaultTilesUrl,
);
/// Key with the `tiles` scope, given at build time:
/// flutter run --dart-define=UPDRAFT_TILES_KEY=upd_...
/// Empty: the public tile path (limited per client address, not counted for you).
const updraftTilesKey = String.fromEnvironment('UPDRAFT_TILES_KEY');
/// Opens the attribution rules page.
void openAttributionRules() => launchUrl(Uri.parse(attributionRulesUrl));
class RasterMapScreen extends StatelessWidget {
const RasterMapScreen({super.key, this.dark = false});
/// `pilot-dark` instead of `pilot-light`.
final bool dark;
@override
Widget build(BuildContext context) => FlutterMap(
options: const MapOptions(
initialCenter: LatLng(36.56, 29.17), // Babadağ, Fethiye
initialZoom: 12,
maxZoom: 17,
),
children: [
// Raster template with {r} (@2x on dense screens), zoom 5–16 drawn and scaled beyond, the
// key as the X-Api-Key header, tiles kept 30 days without asking the network.
updraftTileLayer(
context,
theme: dark ? UpdraftTheme.dark : UpdraftTheme.light,
apiKey: updraftTilesKey,
tilesUrl: updraftTiles,
userAgentPackageName: 'com.example.updraft_quickstart',
),
// Visible attribution line (wraps on narrow screens), not folded into a menu.
const UpdraftAttribution(onTap: openAttributionRules),
],
);
}
Run (the key is optional):
flutter run --dart-define=UPDRAFT_TILES_KEY=upd_…
The whole example app (pubspec.yaml, main.dart; raster and vector map in two tabs) is in the repository under devdocs/examples/flutter/. Platform folders are not kept; run flutter create . once.
3. What updraftTileLayer sets
| Setting | Why |
|---|---|
minNativeZoom: 5, maxNativeZoom: 16 |
Updraft draws z5–16; there are no tiles outside (404). flutter_map scales the z16 tile at z17 and the z5 tiles below z5. Without these two lines the map goes blank when you zoom in |
{r} + retinaMode |
Asks for @2x (512 px, same area) on high-density screens; tiles are 3–4 times larger. Drop it to save data |
headers: {'X-Api-Key': …} |
The key goes in a header, not in the URL. A key inside an app can be extracted: use a key with the tiles scope only |
cacheFor: 30 days (overrideFreshAge) |
Updraft tiles are fresh for an hour (Cache-Control: max-age=3600); without a network flutter_map drops stale tiles. Extending freshness on the client keeps the map when there is no signal on the mountain. The base map is rebuilt monthly |
userAgentPackageName |
Your app's package name; server load is tracked per client |
Dark theme: theme: UpdraftTheme.dark (pilot-dark in the address). Without the package, give TileLayer the values in the table yourself; the address is https://maps.updraftmaps.com/raster/pilot-light/{z}/{x}/{y}{r}.png.
4. What raster tiles contain
The base map: land cover, water, roads, cable cars, contours, hillshade, power lines and labels. The thermal grid, skyways, take-offs and landings are not in raster tiles: these layers depend on thresholds, moderation and consent withdrawal and are not baked into PNGs that stay cached for hours. Use vector tiles (maplibre_gl) or the API (GET /v1/sites) for them.
5. Attribution
The line must stay visible on the map, not folded into a menu. flutter_map's RichAttributionWidget folds the text behind a button, so the package's UpdraftAttribution draws its own small line (it wraps on narrow screens). Rules: Attribution.