Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
This update brings support for Dart 3 and Flutter 3.10.
We've updated some dependencies, including 'latlong2' (to 0.9.0) and 'http' (1.0.0)!
LatLng
objects now have const
constructors to improve performance. To automatically insert the const
keyword where necessary, run dart fix
.
There are a few minor breaking changes for some users, but most changes are internal and need no work to take advantage of.
Please refer to the sections below for information on how to migrate your project. This will contain the changes that most users may need to make, but not all changes. It also excludes some deprecations where the message is self-descriptive.
For a full list of changes, please see the full CHANGELOG, and make use of the old and new API reference.
It is recommended to make the map as large as possible, to allow it to display a lot of useful information easily.
As such, we recommend using a depth-based layout (eg. using Stack
s) instead of a flat-based layout (eg. using Column
s). The following 3rd party packages might help with creating a modern design:
If you must restrict the widget's size, you won't find a height
or width
property. Instead, use a SizedBox
or Column
/Row
& Expanded
.
The map will expand as much as possible.
To avoid errors about infinite/unspecified dimensions, ensure the map is contained within a known size widget.
nonRotatedChildren
Similar to children
, but these don't rotate or move with the other layers.
It is important to note that 'flutter_map' only supports raster tiles natively. Vector tiles can be used with a community maintained plugin.
This is described in more detail at the bottom of this page.
There are 2 main types of tiles a server can serve: raster and vector; each has their own advantages and drawbacks. This page is designed to help you choose a type for your app, and help you use vector tiles if you choose to.
Raster tiles are the 'older' type of tile, and are raster images (usually .png or .jpg). These tiles are good because they can render quickly and easily, can be viewed without special software, and are readily available from most mapping services. As such, this makes them the popular choice for beginners.
However, raster tiles cannot be easily themed: a theme needs a whole new set of map tiles. This makes apps using light and dark themes have mismatching maps. As well as this, raster tiles usually have larger file sizes meaning slower download times, and they can become blurred/pixelated when viewed at a larger scale: a problem for users when zooming between zoom levels. Another issue is that shapes/text inside tiles cannot be rotated, hence the name 'static tiles': therefore, rotating the map will not rotate the name of a road, for example.
Vector tiles can be considered the 'newer' standard. These images might contain a specialised format (such as .pbf) dictating the mathematics and coordinates used to draw lines and shapes. Because these tiles are drawn at render time instead of at request/server time, theming can be used to make the map fit in better with an app's theme. The math-based image means that the images/tiles can be scaled without any loss of clarity.
However it does add complexity to the rendering process as each element needs to be parsed and painted individually, meaning an impact to performance. Text elements and certain shapes can also be rotated (unlike raster tiles) to match the user's orientation, not the orientation of the map; but calculating this rotation needs to be done every frame, meaning an even larger impact on performance.
Due to the complications mentioned above, 'flutter_map' does not natively support vector tiles. However, vector tiles can be used with a community maintained plugin (vector_map_tiles
) to do this.
Mapping package for Flutter, based off of 'leaflet.js'. Simple and easy to learn, yet completely customizable and configurable, it's the best choice for mapping in your Flutter app.
This documentation applies to v5 only!
Use the version selector in the top left to choose documentation suitable for your version.
Setting up an interactive and map is simpler than making your lunch-time coffee! It can be accomplished in just under 30 lines and a minute or two to install.
This code snippet demonstrates everything you need for a simple map (in just over 20 lines!), but of course, FM is capable of much more than just this, and you could find yourself lost in the many options available and possibilities opened!
Not quite sure about something? No problem. Please get in touch via any of these methods, and we'll be with you as soon as possible. Please remember that we are volunteers, so we cannot guarantee (fast) support.
For bug reports & feature requests: GitHub Issues
For general support & everything else: flutter_map Discord server
Due to time shortages and other internal matters, wait times for feature request implementations are currently extremely long and may not happen at all.
We'd love to have your contributions to add your own or others' pull requests!
To dictate what the map can/should do, regardless of its contents, it needs some guidance!
It provides options that can be categorized into three main parts:
Initial positioning Defines the location of the map when it is first loaded
Permanent rules Defines restrictions that last throughout the map's lifetime
Event handling Defines methods that are called on specific map events
One part of MapOptions
responsibilities is to define how the map should be positioned when first loaded. There's two ways to do this (that are incompatible):
center
& zoom
Defines the center coordinates of the map and a zoom level
bounds
Defines an area with two/four coordinates that the viewport should fit to
It is possible to also set the map's rotation
in degrees, if you don't want it North (0°) facing initially.
Changing these properties after the map has already been built for the first time will have no effect: they only apply on initialisation.
To control the map programatically, use a MapController
: Controller.
One part of MapOptions
responsibilities is to define the restrictions and limitations of the map and what users can/cannot do with it.
You should check all the available options, but these are recommended for most maps:
maxZoom
(and minZoom
)
Limits how far the map can be zoomed by the user, to avoid showing empty tiles
maxBounds
Limits how far the map can be moved by the user to a coordinate-based boundary
interactiveFlags
- see InteractiveFlag
for available options
Limits what methods the user can interact with the map through (for example, preventing rotation)
keepAlive
If FlutterMap
is located inside a PageView
, ListView
or another complex lazy layout, set this true
to prevent the map from resetting to the #initial-positioning on rebuild
Instead of maxZoom
(or in addition to), consider setting maxNativeZoom
per TileLayer
instead, to allow tiles to scale (and lose quality) on the final zoom level, instead of setting a hard limit.
To programatically interact with the map (such as panning, zooming and rotating) and receive it's events, you'll need a MapController
.
If building a custom layer (), consider using FlutterMapState
directly instead.
To use a MapController
, it must initialised like any other object and then passed to the FlutterMap
. This attaches them until the map is disposed.
Avoid disconnecting the map from the controller, as it can cause problems. If you need to change the map's contents:
Change its children
(layers) individually
Re-initialise a new MapController
, and keep it in an external state system
initState()
It is a fairly common requirement to need to use the MapController
in initState()
, before the map has been built. Unfortunately, this is not possible, as the map must be built for the controller to be attached.
That method will, however, not work if the map is not built on the first frame. This may be the case if it is, for example, in a FutureBuilder
.
Using them as a reaction to a map event is still fine.
The example application also includes a page demonstrating a custom animated map movement without the plugin.
If you still get issues, and FlutterMap
is located inside a PageView
, ListView
or another complex lazy layout, try setting keepAlive
true
in MapOptions
: .
This isn't a problem however! The MapOptions
contains an onMapReady
callback (see ) is called when the map is initialised, and the initialised map controller can be used freely within it.
It may also be possible to use SchedulerBinding
or WidgetsBinding
in initState
to run a method after the first frame has been built, as detailed here: . You'll probably see this approach in many older projects.
MapController
methods that change the position of the map should not be used instantly in onMapReady
- see .
Whilst animated movements through MapController
s aren't built-in, the provides this, and much more!