The tileProvider
parameter in TileLayer
takes a TileProvider
object specifying a tile provider to use for that layer.
This has a default of NetworkTileProvider
which gets tiles from the internet through a dedicated image provider.
There's two situations in which you'll need to change the tile provider:
Sourcing tiles from the filesystem or asset store: #local-tile-providers
Using a plugin that instructs you to do so (Creating New Tile Providers)
These tile providers use the urlTemplate
to get the appropriate tile from the a network, usually the World Wide Web.
The underlying custom ImageProvider
s will cache tiles in memory, so that they do not require another request to the tile server if they are pruned then re-loaded. This should result in them being loaded quicker, as well as enabling already loaded tiles to appear even without Internet connection (at least in the same session).
Specifying any fallbackUrl
(even if it is not used) in the TileLayer
will prevent loaded tiles from being cached in memory.
This is to avoid issues where the urlTemplate
is flaky (sometimes works, sometimes doesn't), to prevent potentially different tilesets being displayed at the same time.
NetworkTileProvider
This is the default tile provider, and does nothing particularly special. It takes two arguments, but you'll usually never need to specify them:
httpClient
: BaseClient
By default, a RetryClient
backed by a standard Client
is used
headers
: Map<String, String>
By default, only headers sent by the platform are included with each request, plus an overridden (where possible) 'User-Agent' header based on the #useragentpackagename property
This requires the 'flutter_map_cancellable_tile_provider' plugin to be installed.
This plugin is part of the official 'flutter_map' organisation, and maintained by the same maintainers.
Tiles that are removed/pruned before they are fully loaded do not need to complete (down)loading, and therefore do not need to complete the HTTP interaction. Cancelling these unnecessary tile requests early could:
Reduce tile loading durations (particularly on the web)
Reduce users' (cellular) data and cache space consumption
Reduce costly tile requests to tile servers*
Improve performance by reducing CPU and IO work
This provider uses 'dio', which supports aborting unnecessary HTTP requests in-flight, after they have already been sent.
Although HTTP request abortion is supported on all platforms, it is especially useful on the web - and therefore recommended for web apps. This is because the web platform has a limited number of simulatous HTTP requests, and so closing the requests allows new requests to be made for new tiles. On other platforms, the other benefits may still occur, but may not be as visible as on the web.
Once HTTP request abortion is added to Dart's 'native' 'http' package (which already has a PR opened), NetworkTileProvider
will be updated to take advantage of it, replacing and deprecating this provider. This tile provider is currently a separate package and not the default due to the reliance on the additional Dio dependency.
These tile providers use the urlTemplate
to get the appropriate tile from the asset store of the application, or from a file on the users device, respectively.
Specifying any fallbackUrl
(even if it is not used) in the TileLayer
will reduce the performance of these providers.
It will cause 23% slower asset tile requests with AssetTileProvider
, and will cause main thread blocking when requesting tiles from FileTileProvider
.
AssetTileProvider
This tile providers uses the templateUrl
to get the appropriate tile from the asset store of the application.
Asset management in Flutter leaves a lot to be desired! Unfortunately, every single sub-directory (to the level of tiles) must be listed.
FileTileProvider
This tile providers uses the templateUrl
to get the appropriate tile from the a path/directory/file on the user's device - either internal application storage or external storage.
On the web, FileTileProvider()
will throw an UnsupportedError
when a tile request is attempted, due to the lack of the web platform's access to the local filesystem.
If you know you are running on the web platform, use a NetworkTileProvider
or a custom tile provider.
The basis of any map is a TileLayer
, which displays square raster images in a continuous grid, sourced from the Internet or a local file system.
flutter_map supports WMS Usage, but most map tiles are accessed through Slippy Map/CARTO/XYZ URLs.
You must comply with the appropriate restrictions and terms of service set by your tile server. Failure to do so may lead to any punishment, at the tile server's discretion.
This library and/or the creator(s) are not responsible for any violations you make using this package.
The OpenStreetMap Tile Server (as used above) ToS can be found here. Other servers may have different terms.
This parameter must be specified unless wmsOptions
is specified.
The URL template is a string that contains placeholders, which, when filled in, create a URL/URI to a specific tile.
Specifically, flutter_map supports the Slippy Map format, sometimes referred to as CARTO or Raster XYZ. Tiles are referred to by their zoom level, and position on the X & Y axis. For more information, read How Does It Work?.
These templates are usually documented by your tile server, and will always include the following placeholders:
{x}
: x axis coordinate
{y}
: y axis coordinate
{z}
: zoom level
Sometimes, they also include:
{s}
: #subdomains
{r}
: #retina-mode
Additional placeholders can also be added freely to the template, and are filled in with the specified values in additionalOptions
. This can be used to easier add switchable styles or access tokens, for example.
Some tile servers provide mirrors/redirects of the main tile server on/via subdomains, such as 'a', 'b', 'c'.
These were necessary to bypass browsers' limitations on simultaneous HTTP connections, thus increasing the number of tiles that can load at once.
To use subdomains, add the {s}
placeholder, and specify the available subdomains in TileLayer.subdomains
. flutter_map will then fill the placeholder with one of these values based on internal logic.
Subdomains are now usually considered redundant due to the usage of HTTP/2 & HTTP/3 which don't have the same restrictions.
Usage of subdomains will also hinder Flutter's ability to cache tiles, potentially leading to increased tile requests and costs.
If the server supports HTTP/2 or HTTP/3 (how to check), avoid using subdomains.
Retina mode improves the resolution of map tiles, an effect particularly visible on high density displays.
Raster map tiles can look pixelated (especially on high density displays), so some servers support high-resolution "@2x" tiles, which are tiles at twice the resolution of normal tiles. However, not all tile servers support this, so flutter_map can simulate retina behaviour.
It is recommended to enable retina mode on high density displays (especially where the server natively supports retina tiles). This can be done by calling RetinaMode.isHighDensity
with the current BuildContext
, and passing the result to TileLayer.retinaMode
.
If the {r}
placeholder is present in the the urlTemplate
, and retinaMode
is enabled, then it will be filled with "@2x".
If it is not present, but retinaMode
is enabled, then flutter_map will simulate retina behaviour by requesting four tiles at a larger zoom level and combining them together in place of one.
Note that simulating retina mode will increase tile requests, decrease the effective maximum zoom by 1, and may result in map labels/text/POIs appearing smaller than normal.
Always prefer the server's native retina tiles where available.
It's also possible to specify a fallbackUrl
template, used if fetching a tile from the primary urlTemplate
fails (which has the same format as this).
Specifying a fallbackUrl
does have negative effects on performance and efficiency. Avoid specifying fallbackUrl
unless absolutely necessary for your use case.
See in-code documentation and Tile Providers for more information.
userAgentPackageName
Although it is programatically optional, always specify the userAgentPackageName
argument to avoid being blocked by your tile server.
This parameter should be passed the application's package name, such as 'com.example.app'. This is important to avoid blocking by tile servers due to high-levels of unidentified traffic. If no value is passed, it defaults to 'unknown'.
This is then formatted into a 'User-Agent' header, and appended to the TileProvider
's headers
map, if it is not already present.
This is ignored on the web, where the 'User-Agent' header cannot be changed due to a limitation of Dart/browsers.
If a large proportion of your users use the web platform, it is preferable to use CancellableNetworkTileProvider
, instead of the default NetworkTileProvider
. It may also be beneficial to use this tile provider on other platforms as well.
See #cancellablenetworktileprovider for more information.
Need more control over how the URL template is interpreted and/or tiles are fetched? You'll need to change the TileProvider
.
flutter_map supports WMS tile servers through WMSTileLayerOptions
- wmsOptions
in TileLayer
s.
For usage, please refer to the Full API Reference, and the examples in the example app.
Omit urlTemplate
if using WMS tiles. The template is now specified in the baseUrl
property of WMSTileLayerOptions
.