Displaying Radar Maps with Flutter
To create a Flutter component with a map:
The SDK has a dependency on maplibre_gl. See the source on GitHub here. Or, see the flutter_radar
package on pub.dev here.
#
InstallAdd the package to your pubspec.yaml
file:
dependencies: flutter_radar: ^3.12.2
Then, update dependencies:
flutter pub get
Next, complete any required platform-specific installation steps for maplibre_gl.
#
Radar MapOnce installation is complete, initialize the Radar SDK and add a MapLibreMap
component:
import 'package:flutter/material.dart';import 'package:maplibre_gl/maplibre_gl.dart';
void main() { runApp(RadarMapsDemo());}
String style = "radar-default-v1"; // specify styleId here for custom Map styleString publishableKey = "prj_test_pk_...";
class RadarMapsDemo extends StatelessWidget { const RadarMapsDemo({super.key});
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MapLibreMap( styleString: 'https://api.radar.io/maps/styles/$style/?publishableKey=$publishableKey', initialCameraPosition: const CameraPosition( target: LatLng(40.7342891, -73.9910334), // initial position (Radar HQ) zoom: 12.0, ), tiltGesturesEnabled: false, // disable tilt gestures rotateGesturesEnabled: false, // disable rotate gestures onMapCreated: (MapLibreMapController controller) { // You can add any additional setup here if needed }, ), ), ); }}
#
Radar Map w/ MarkerOptionally, add assets for a marker. You can download assets here. Once downloaded, add marker assets to images/
dir.
To add a marker to the map and display text once it's clicked:
import 'dart:async';import 'dart:ui' as ui;import 'package:flutter/material.dart';import 'package:flutter/services.dart';import 'package:maplibre_gl/maplibre_gl.dart';
void main() { runApp(RadarMapsDemo());}
class RadarMapsDemo extends StatefulWidget { const RadarMapsDemo({super.key});
@override RadarMapsState createState() => RadarMapsState();}
String style = "radar-default-v1"; // specify styleId here for custom Map styleString publishableKey = "prj_test_pk_...";
class RadarMapsState extends State<RadarMapsDemo> { late MapLibreMapController mapController; List<Symbol> markers = []; Symbol? hqMarker; Symbol? selectedMarker; LatLng? infoWindowPosition; bool showInfoWindow = false; String infoWindowText = ""; bool isCameraMovingProgrammatically = false;
@override void initState() { super.initState(); }
// async helper function to load image from assets Future<ui.Image> _loadImage(Uint8List img) async { final Completer<ui.Image> completer = Completer(); ui.decodeImageFromList(img, (ui.Image img) { return completer.complete(img); }); return completer.future; }
// helper to prepare images for map use Future<void> _addImageFromAsset(String name, String assetName) async { final ByteData data = await rootBundle.load(assetName); final ui.Image image = await _loadImage(Uint8List.view(data.buffer)); final ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png); final Uint8List imgBytes = byteData!.buffer.asUint8List(); mapController.addImage(name, imgBytes); }
// Function to add marker on the map void _addMarker(LatLng latLng) async { final Symbol marker = await mapController.addSymbol( SymbolOptions( geometry: latLng, iconImage: "marker", iconSize: 1, ), ); markers.add(marker);
if (latLng == const LatLng(40.7342891, -73.9910334)) { hqMarker = marker; } }
// Handle tap on marker void _onMarkerTapped(Symbol symbol) { String text = symbol == hqMarker ? "Radar HQ" : "Marker ${markers.indexOf(symbol) + 1}";
setState(() { selectedMarker = symbol; infoWindowPosition = symbol.options.geometry; showInfoWindow = true; infoWindowText = text; });
_centerMapOnPosition(symbol.options.geometry!); }
// Center map on given LatLng void _centerMapOnPosition(LatLng latLng) { setState(() { isCameraMovingProgrammatically = true; });
mapController.animateCamera( CameraUpdate.newCameraPosition( CameraPosition(target: latLng, zoom: 14.0), ), ).then((_) { Future.delayed(const Duration(seconds: 1), () { setState(() { isCameraMovingProgrammatically = false; }); }); }); }
// Callback on map initialization void _onMapCreated(MapLibreMapController controller) async { mapController = controller; mapController.onSymbolTapped.add(_onMarkerTapped); await mapController.setSymbolIconAllowOverlap(true); await mapController.setSymbolIconIgnorePlacement(true);
// Add images for markers await _addImageFromAsset("marker", "images/marker.png");
// Add HQ marker to the map _addMarker(const LatLng(40.7342891, -73.9910334)); }
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Stack( children: [ // Map rendering MapLibreMap( styleString: 'https://api.radar.io/maps/styles/$style?publishableKey=$publishableKey', initialCameraPosition: const CameraPosition( target: LatLng(40.7342891, -73.9910334), zoom: 12.0, ), tiltGesturesEnabled: false, rotateGesturesEnabled: false, onMapCreated: _onMapCreated, ),
// Info window if (showInfoWindow && infoWindowPosition != null) Positioned( top: MediaQuery.of(context).padding.top + 16, left: 0, right: 0, child: Center( child: Card( child: Padding( padding: const EdgeInsets.all(8), child: Text(infoWindowText), ), ), ), ), ], ), ), ); }}
See our flutter maps example repo for more info.