From 0349323a7b288f9b8e882f09c74cc1f78b327348 Mon Sep 17 00:00:00 2001 From: JaffaKetchup Date: Tue, 29 Aug 2023 11:57:54 +0100 Subject: [PATCH 1/2] Implemented equality operation for `FlutterMapNetworkImageProvider` --- .../tile_provider/network_image_provider.dart | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) 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..25b924c8a 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,8 @@ 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. @immutable class FlutterMapNetworkImageProvider extends ImageProvider { @@ -17,12 +19,18 @@ class FlutterMapNetworkImageProvider final String? fallbackUrl; /// The HTTP client to use to make network requests + /// + /// Not included in [operator==] calculations. final BaseClient httpClient; /// The headers to include with the tile fetch request + /// + /// Not included in [operator==] calculations. 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. const FlutterMapNetworkImageProvider({ required this.url, required this.fallbackUrl, @@ -75,4 +83,14 @@ class FlutterMapNetworkImageProvider return decode(await ImmutableBuffer.fromUint8List(bytes)); } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is FlutterMapNetworkImageProvider && + url == other.url && + fallbackUrl == other.fallbackUrl; + + @override + int get hashCode => Object.hash(url, fallbackUrl); } From 7e4c1b73caa73bc4a765467f89c67f2d3022ba86 Mon Sep 17 00:00:00 2001 From: JaffaKetchup Date: Fri, 1 Sep 2023 11:24:55 +0100 Subject: [PATCH 2/2] Prevent caching/equality if `fallbackUrl` is non-null Improved documentation --- lib/src/layer/tile_layer/tile_layer.dart | 22 ++++++++----------- .../tile_provider/network_image_provider.dart | 21 +++++++++++++----- 2 files changed, 24 insertions(+), 19 deletions(-) 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 25b924c8a..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 @@ -8,6 +8,8 @@ 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 { @@ -16,21 +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==] calculations. + /// Not included in [operator==]. final BaseClient httpClient; /// The headers to include with the tile fetch request /// - /// Not included in [operator==] calculations. + /// Not included in [operator==]. final Map headers; /// 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, @@ -87,10 +95,11 @@ class FlutterMapNetworkImageProvider @override bool operator ==(Object other) => identical(this, other) || - other is FlutterMapNetworkImageProvider && - url == other.url && - fallbackUrl == other.fallbackUrl; + (other is FlutterMapNetworkImageProvider && + fallbackUrl == null && + url == other.url); @override - int get hashCode => Object.hash(url, fallbackUrl); + int get hashCode => + Object.hashAll([url, if (fallbackUrl != null) fallbackUrl]); }