arrow-left

All pages
gitbookPowered by GitBook
1 of 3

Loading...

Loading...

Loading...

Tile Layer

circle-exclamation

You must comply with the appropriate restrictions and terms of service set by your tile server. Always read the ToS before using a 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 below) ToS can be . Other servers may have different terms.

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 , but most map tiles are accessed through Slippy Map/CARTO/XYZ URLs, as described here.

hashtag
Recommended Setup

circle-check

Although setting up a basic tile layer couldn't be simpler, it helps to spend a little bit more time fine-tuning it! We recommend covering this list at least, for every tile layer.

  • (required, except when using WMS) Choose a suitable tile server for your app

  • Always set userAgentPackageName, even though it is technically optional

  • If your tile server supports retina tiles natively, set up the retinaMode property

If you need to squeeze out as much performance as possible, or you're noticing the tile loading seems a little slow:

  • Make sure the FlutterMap is rebuilt as few times as possible

  • Construct the TileProvider yourself, outside of the build method if possible, so it is reconstructed as few times as possible Some tile providers may perform more expensive logic when they are constructed, and if the provider is frequently reconstructed, this can add up.

hashtag
Main Parameters

hashtag
URL Template

circle-check

This parameter must be specified unless 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 .

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}

Sometimes, they also include:

  • {s}:

  • {r}:

  • {d}

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.

hashtag
Subdomains

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.

circle-exclamation

Subdomains are now usually 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 (), avoid using subdomains.

hashtag
Retina Mode

Retina mode improves the resolution of map tiles, an effect particularly visible on high density (aka. retina) displays.

Raster map tiles can look especially pixelated on retina displays, so some servers support , which are tiles at twice the resolution of normal tiles.

Where the display is high density, and the server supports retina tiles - usually indicated by an {r} placeholder in the URL template - it is recommended to enable retina mode.

circle-check

Therefore, where {r} is available, it is recommended to call the method RetinaMode.isHighDensity with the current BuildContext, and pass the result to TileLayer.retinaMode. This will enable retina mode on retina displays by filling the {r} placeholder with "@2x".

Note that where tiles are larger than the standard x256px (such as x512px), retina mode can help make them appear very similar to x256px tiles, but still retain the other benefits of larger tiles. In this case, consider fixing retinaMode to true, depending on your own tests. See for more information.

circle-exclamation

It is also possible to emulate retina mode, even when the server does not natively support it. If retinaMode is true, and no {r} placeholder is present, flutter_map will emulate it by requesting four tiles at a larger zoom level and combining them together in place of one.

Emulating retina mode has multiple negative effects:

hashtag
Fallback URL Template

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).

circle-exclamation

Specifying a fallbackUrl does have negative effects on performance and efficiency. Avoid specifying fallbackUrl unless necessary.

See in-code documentation and for more information.

circle-exclamation

Some TileProviders may not support/provide any functionality for fallbackUrl template.

hashtag
userAgentPackageName

circle-check

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.

hashtag
Tile Providers

circle-check

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 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.

hashtag
tileSize

Some tile servers will use 512x512px tiles instead of 256x256px, such as Mapbox. Using these larger tiles can help reduce tile requests, and when combined with , it can give the same resolution.

To use these tiles, set tileSize to the actual dimensions of the tiles (otherwise they will appear to small), such as 512. Also set zoomOffset to the result of -((d/256) - 1) - ie. -1 for x512px tiles (otherwise they will appear at the wrong geographical locations).

The {d} placeholder/parameter may also be used in the URL to pass through the value of tileSize.

hashtag
panBuffer

To make a more seamless experience, tiles outside the current viewable area can be 'preloaded', with the aim of minimizing the amount of non-tile space a user sees.

panBuffer sets the number of surrounding rows and columns around the viewable tiles that should be loaded, and defaults to 1.

circle-exclamation

Specifying a panBuffer too high may result in slower tile requests for all tiles (including those that are visible), and a higher load on the tile sever. The effect is amplified on larger map dimensions/screen sizes.

hashtag
Tile Update Transformers

circle-info

TileUpdateTransformer(s) is a power-user feature. Most applications won't require it.

A TileUpdateTransformer restricts and limits TileUpdateEvents (which are emitted 'by' MapEvents), which cause tiles to update.

For example, a transformer can delay (throttle or debounce) updates through one of the built-in transformers, or pause updates during an animation, or force updates even when a MapEvent wasn't emitted.

For more information, see:

CancellableNetworkTileProvider Especially on web, consider using this more advanced TileProvider to improve performance

  • maxNativeZoomarrow-up-right Set the maximum zoom level that the tile server supports to prevent flutter_map from trying to exceed this (especially when not set appropriately in MapOptions.maxZoom)

  • If the TileProvider supports it (as NetworkTileProvider does), construct a single HTTP Client/HttpClient outside the build method and pass it to the tile provider - especially if you're unable to do the tip above Using a single HTTP client allows the underlying socket connection to the tile server to remain open, even when tiles aren't loading. When tiles are loaded again, it's much faster to communicate over an open socket than opening a new one. In some cases, this can take hundreds of milliseconds off tile loading!
  • Reduce panBufferarrow-up-right to 0 This reduces the number of network requests made, which may make those requests that are made for more important tiles faster.

  • : zoom level
    :
  • it increases tile requests

  • it likely causes text/labels and POI markers embedded in the tiles to become smaller and unreadable

  • it decreases the effective maximum zoom by 1

  • Therefore, carefully consider whether emulating retina mode is appropriate for your application, and disable it if necessary. Always prefer native retina tiles if they are available.

    found herearrow-up-right
    WMS Usage
    wmsOptions
    How Does It Work?
    considered redundantarrow-up-right
    how to checkarrow-up-right
    high-resolution "@2x" tilesarrow-up-right
    Tile Providers
    Tile Providerschevron-right
    Retina Mode
    URL Template
    userAgentPackageName
    Retina Mode
    Subdomains
    Retina Mode
    tileSize
    tileSize
    CancellableNetworkTileProvider

    Tile Providers

    The tileProvider parameter in TileLayer takes a TileProvider object specifying a 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:

    TileLayer(
      urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
      userAgentPackageName: 'dev.fleaflet.flutter_map.example',
      // Plenty of other options available!
    ),

    Sourcing tiles from the filesystem or asset store: Local Tile Providers

  • Using a plugin that instructs you to do so (Creating New Tile Providers)

  • hashtag
    Network 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 ImageProviders 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).

    circle-exclamation

    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.

    hashtag
    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 property

    hashtag
    CancellableNetworkTileProviderarrow-up-right

    circle-info

    This requires the 'flutter_map_cancellable_tile_providerarrow-up-right' 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 'dioarrow-up-right', 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)arrow-up-right, 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.

    hashtag
    Local Tile Providers

    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.

    circle-exclamation

    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 requestsarrow-up-right with AssetTileProvider, and will cause main thread blocking when requesting tiles from FileTileProvider.

    hashtag
    AssetTileProvider

    This tile providers uses the templateUrl to get the appropriate tile from the asset store of the application.

    circle-info

    Asset management in Flutter leaves a lot to be desired! Unfortunately, every single sub-directory (to the level of tiles) must be listed.

    hashtag
    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.

    circle-exclamation

    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.

    hashtag
    Offline Mapping

    tile provider
    Offline Mappingchevron-right

    WMS Usage

    flutter_map supports WMS tile servers through WMSTileLayerOptions - wmsOptions in TileLayers.

    For usage, please refer to the Full API Reference, and the examples in the example app.

    circle-check

    Omit urlTemplate

    userAgentPackageName
    if using WMS tiles. The template is now specified in the
    baseUrl
    property of
    WMSTileLayerOptions
    .
    TileUpdateTransformer typedef - flutter_map library - Dart APIpub.devchevron-right
    Logo
    TileLayer class - flutter_map library - Dart APIpub.devchevron-right
    Logo
    WMSTileLayerOptions class - flutter_map library - Dart APIpub.devchevron-right
    Logo