Creating a new map layer is a great way to achieve a more custom, performant, map design. For example, it might be used to display a scale bar, or overlay a grid.
Check the Plugins List for layers that already implement the behaviour you wish to replicate.
It starts with a normal StatelessWidget
or StatefulWidget
, which then starts its widget tree with a widget dependent on whether the layer is designed to be either 'mobile' or 'static', depending on the purpose of the layer. For more information, see #mobile-vs-static-layers.
Then, there are three possible methods that could be used to retrieve separate 'aspects' of the state of the map.
Calling these inside a build
method will also cause the layer to rebuild automatically when the depended-on aspects change.
Using these methods will restrict this widget to only being usable inside the context of a FlutterMap
.
One common requirement is a custom TileProvider
, and potentially a custom ImageProvider
inside. This will allow your plugin to intercept all tile requests made by a map, and take your own action(s), before finally returning a tile.
Check the Plugins List for providers that already implement the behaviour you wish to replicate.
TileProvider
To create your own usable TileProvider
, the first step is making a class that extends
the abstract class, and adding a constructor.
The constructor should accept an argument of super.headers
, without a const
ant default.
If using an object that needs closing/cancelling, such as an HttpClient
, override the dispose
method.
TileProvider
s must implement a method to return an ImageProvider
(the image of a tile), given its coordinates and the TileLayer
it is used within.
It is best to put as much logic as possible into a custom ImageProvider
, to avoid blocking the main thread.
There's two methods that could be called by flutter_map internals to retrieve a tile: getImage
or getImageWithCancelLoadingSupport
.
Prefer overriding getImageWithCancelLoadingSupport
for TileProvider
s that can cancel the loading of a tile in-flight, if the tile is pruned before it is fully loaded. An example of a provider that may be able to do this is one that makes HTTP requests, as HTTP requests can be aborted on the web (although Dart does not 'natively' support it yet, so a library such as Dio is necessary). Otherwise, getImage
must be overridden.
In addition to the coordinates and TileLayer
, the method also takes a Future<void>
that is completed when the tile is pruned. It should be listened to for completion (for example, with then
), then used to trigger the cancellation.
For an example of this, see #cancellablenetworktileprovider.
If developing a plugin, you may wish to adjust the 'User-Agent' header has been to further differentiate your plugin's traffic from vanilla 'flutter_map' traffic.
Some custom TileProvider
s may want to change the way URLs are generated for tiles, given a coordinate.
It's possible to override:
how the urlTemplate
's placeholders are populated: populateTemplatePlaceholders
the values used to populate those placeholders: generateReplacementMap
the generation method itself: getTileUrl
and/or getTileFallbackUrl
Avoid overriding the generation method itself, as it is not usually necessary.
If one of the independently maintained plugins doesn't suit your needs, then you can create your own, to achieve maximum customizability.
Most plugins create either new Tile Providers, or new Layers. Some plugins just provide additional useful tools.
If you've made your own plugin that you're willing to share, please let us know in the #plugins channel on the flutter_map Discord server. We can then add it to the Plugins List. We're always looking forward to see what you've made!
When submitting a plugin, please ensure the plugin:
preferably includes 'flutter_map_' in the name, by convention
is preferably available via a standard pub.dev package installation
includes good documentation (at least to setup basic functionality), and a code example