diff --git a/lib/src/layer/tile_layer/tile_layer.dart b/lib/src/layer/tile_layer/tile_layer.dart index bc20f5355..2e2a3a47a 100644 --- a/lib/src/layer/tile_layer/tile_layer.dart +++ b/lib/src/layer/tile_layer/tile_layer.dart @@ -24,22 +24,18 @@ part 'wms_tile_layer_options.dart'; /// avoid issues. @immutable class TileLayer extends StatefulWidget { - /// Defines the structure to create the URLs for the tiles. `{s}` means one of - /// the available subdomains (can be omitted) `{z}` zoom level `{x}` and `{y}` - /// — tile coordinates `{r}` can be used to add "@2x" to the URL to - /// load retina tiles (can be omitted) + /// The URL template is a string that contains placeholders, which, when filled + /// in, create a URL/URI to a specific tile. /// - /// Example: - /// - /// https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png - /// - /// Is translated to this: - /// - /// https://a.tile.openstreetmap.org/12/2177/1259.png + /// For more information, see . final String? urlTemplate; - /// Follows the same structure as [urlTemplate]. If specified, this URL is - /// used only if an error occurs when loading the [urlTemplate]. + /// Fallback URL template, used if an error occurs when fetching tiles from + /// the [urlTemplate]. + /// + /// Note that specifying this (non-null) will result in tiles not being cached + /// in memory. This is to avoid issues where the [urlTemplate] is flaky, to + /// prevent different tilesets being displayed at the same time. /// /// Avoid specifying this when using [AssetTileProvider] or [FileTileProvider], /// as these providers are less performant and efficient when this is diff --git a/lib/src/layer/tile_layer/tile_provider/network_image_provider.dart b/lib/src/layer/tile_layer/tile_provider/network_image_provider.dart index 00faee442..67174f1d8 100644 --- a/lib/src/layer/tile_layer/tile_provider/network_image_provider.dart +++ b/lib/src/layer/tile_layer/tile_provider/network_image_provider.dart @@ -6,6 +6,10 @@ import 'package:flutter/painting.dart'; import 'package:http/http.dart'; /// Dedicated [ImageProvider] to fetch tiles from the network +/// +/// Supports falling back to a secondary URL, if the primary URL fetch fails. +/// Note that specifying a [fallbackUrl] will prevent this image provider from +/// being cached. @immutable class FlutterMapNetworkImageProvider extends ImageProvider { @@ -14,15 +18,27 @@ class FlutterMapNetworkImageProvider /// The URL to fetch the tile from (GET request), in the event the original /// [url] request fails + /// + /// If this is non-null, [operator==] will always return `false` (except if + /// the two objects are [identical]). Therefore, if this is non-null, this + /// image provider will not be cached in memory. final String? fallbackUrl; /// The HTTP client to use to make network requests + /// + /// Not included in [operator==]. final BaseClient httpClient; /// The headers to include with the tile fetch request + /// + /// Not included in [operator==]. final Map headers; - /// Dedicated [ImageProvider] to fetch tiles from the network + /// Create a dedicated [ImageProvider] to fetch tiles from the network + /// + /// Supports falling back to a secondary URL, if the primary URL fetch fails. + /// Note that specifying a [fallbackUrl] will prevent this image provider from + /// being cached. const FlutterMapNetworkImageProvider({ required this.url, required this.fallbackUrl, @@ -75,4 +91,15 @@ class FlutterMapNetworkImageProvider return decode(await ImmutableBuffer.fromUint8List(bytes)); } + + @override + bool operator ==(Object other) => + identical(this, other) || + (other is FlutterMapNetworkImageProvider && + fallbackUrl == null && + url == other.url); + + @override + int get hashCode => + Object.hashAll([url, if (fallbackUrl != null) fallbackUrl]); }