A Dart implementation of Leaflet for Flutter apps.
Installation
Add flutter_map to your pubspec:
dependencies: flutter_map: any # or the latest version on Pub
Android
Ensure the following permission is present in your Android Manifest file, located in <project root>/android/app/src/main/AndroidManifest.xml
:
<uses-permission android:name="android.permission.INTERNET"/>
Usage
Configure the map using MapOptions
and layer options:
Widget build(BuildContext context) { return new FlutterMap( options: new MapOptions( center: new LatLng(51.5, -0.09), zoom: 13.0, ), layers: [ new TileLayerOptions( urlTemplate: "https://api.tiles.mapbox.com/v4/" "{id}/{z}/{x}/{y}@2x.png?access_token={accessToken}", additionalOptions: { 'accessToken': '<PUT_ACCESS_TOKEN_HERE>', 'id': 'mapbox.streets', }, ), new MarkerLayerOptions( markers: [ new Marker( width: 80.0, height: 80.0, point: new LatLng(51.5, -0.09), builder: (ctx) => new Container( child: new FlutterLogo(), ), ), ], ), ], ); }
Azure Maps provider
Configure the map to use Azure Maps by using the following MapOptions
and layer options:
Widget build(BuildContext context) { return new FlutterMap( options: new MapOptions( center: new LatLng(51.5, -0.09), zoom: 13.0, ), layers: [ new TileLayerOptions( urlTemplate: "https://atlas.microsoft.com/map/tile/png?api-version=1&layer=basic&style=main&tileSize=256&view=Auto&zoom={z}&x={x}&y={y}&subscription-key={subscriptionKey}", additionalOptions: { 'subscriptionKey': '<YOUR_AZURE_MAPS_SUBSCRIPTON_KEY>' }, ), new MarkerLayerOptions( markers: [ new Marker( width: 80.0, height: 80.0, point: new LatLng(51.5, -0.09), builder: (ctx) => new Container( child: new FlutterLogo(), ), ), ], ), ], ); }
To use Azure Maps you will need to setup an account and get a subscription key
Open Street Map provider
Configure the map to use Open Street Map by using the following MapOptions
and layer options:
Widget build(BuildContext context) { return new FlutterMap( options: new MapOptions( center: new LatLng(51.5, -0.09), zoom: 13.0, ), layers: [ new TileLayerOptions( urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", subdomains: ['a', 'b', 'c'] ), new MarkerLayerOptions( markers: [ new Marker( width: 80.0, height: 80.0, point: new LatLng(51.5, -0.09), builder: (ctx) => new Container( child: new FlutterLogo(), ), ), ], ), ], ); }
Custom CRS
By default flutter_map supports only WGS84 (EPSG:4326) and Google Mercator (EPSG:3857) projections. With the integration of proj4dart any coordinate reference systems (CRS) can be defined and used.
Define custom CRS:
var resolutions = <double>[32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128]; var maxZoom = (resolutions.length - 1).toDouble(); var epsg3413CRS = Proj4Crs.fromFactory( code: 'EPSG:3413', proj4Projection: proj4.Projection.add('EPSG:3413', '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'), resolutions: resolutions );
Use Custom CRS in map and in WMS layers:
child: FlutterMap( options: MapOptions( // Set the map's CRS crs: epsg3413CRS, center: LatLng(65.05166470332148, -19.171744826394896), maxZoom: maxZoom, ), layers: [ TileLayerOptions( wmsOptions: WMSTileLayerOptions( // Set the WMS layer's CRS too crs: epsg3413CRS, baseUrl: 'https://www.gebco.net/data_and_products/gebco_web_services/north_polar_view_wms/mapserv?', layers: ['gebco_north_polar_view'], ), ), ], );
For more details visit Custom CRS demo page.
Run the example
See the example/
folder for a working example app.
To run it, in a terminal cd into the folder. Then execute ulimit -S -n 2048
(ref). Then execute flutter run
with a running emulator.
Offline maps
Follow this guide to grab offline tiles
Once you have your map exported to .mbtiles
, you can use mbtilesToPng to unpack into /{z}/{x}/{y}.png
. Move this to Assets folder and add asset directories to pubspec.yaml
. Minimum required fields for offline maps are:
Widget build(ctx) { return FlutterMap( options: MapOptions( center: LatLng(56.704173, 11.543808), zoom: 13.0, swPanBoundary: LatLng(56.6877, 11.5089), nePanBoundary: LatLng(56.7378, 11.6644), ), layers: [ TileLayerOptions( tileProvider: AssetTileProvider(), urlTemplate: "assets/offlineMap/{z}/{x}/{y}.png", ), ], ); }
Make sure PanBoundaries are within offline map boundary to stop missing asset errors.
See the flutter_map_example/
folder for a working example.
Note that there is also FileTileProvider()
, which you can use to load tiles from the filesystem.