diff --git a/README.md b/README.md index 3a151c700..0e0b5204c 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,17 @@ Then execute `ulimit -S -n 2048` ([ref](https://github.com/trentpiercy/trace/iss Then execute `flutter run` with a running emulator. ## Offline maps +Full offline map functionality has been created by JaffaKetchup. Use `PersistentAdvancedCacheTileProvider()` as the `TileLayerOptions > tileProvider` option, and set `TileLayerOptions > saveDir` to a variable containing (await) `getApplicationDocumentsDirectory()` from library [`path_provider`](https://pub.dev/packages/path_provider). + +As the user scrolls around the map, tiles will be saved to `[saveDir]/tiles`. Then, when requested again, tiles will be taken from that directory if available, else a network tile request will be made. Thus, this is a file first solution. + +This configuration should be used where offline functionality is required because cached tiles from other tile providers can be cleaned by the system without user notification at any point. With this setup, only the user (through App Settings > Storage > Clear Storage) or the app itself can clear the tiles. It is up to the app developer (you) to manage these tiles... + +If your user wants to get the latest tiles from the server for tiles already loaded, you must clear the tiles folder. If the user wishes to remove tiles altogether, you must provide that functionality. This library will not handle that for you. + +A recommended (however untested) integration is to use another tile provider (such as the default) whilst not in 'Offline Mode' so that the newest tiles are always loaded, then switch to this provider once the user enters 'Download & Offline Mode'. Then, when the user switches back out, clear the tiles folder. + +## Preconfigured maps (previously 'Offline maps') [Follow this guide to grab offline tiles](https://tilemill-project.github.io/tilemill/docs/guides/osm-bright-mac-quickstart/)
Once you have your map exported to `.mbtiles`, you can use [mbtilesToPng](https://github.com/alfanhui/mbtilesToPngs) to unpack into `/{z}/{x}/{y}.png`. diff --git a/lib/src/layer/tile_layer.dart b/lib/src/layer/tile_layer.dart index 9739a4ec6..436cf0a37 100644 --- a/lib/src/layer/tile_layer.dart +++ b/lib/src/layer/tile_layer.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; @@ -118,6 +119,10 @@ class TileLayerOptions extends LayerOptions { /// TileProvider /// final TileProvider tileProvider; + + // If using PersistentAdvancedCacheTileProvider() + // Set this to: `await getApplicationDocumentsDirectory()` + final Directory saveDir; /// When panning the map, keep this many rows and columns of tiles before /// unloading them. @@ -206,6 +211,7 @@ class TileLayerOptions extends LayerOptions { this.placeholderImage, this.errorImage, this.tileProvider = const CachedNetworkTileProvider(), + this.saveDir, this.tms = false, // ignore: avoid_init_to_null this.wmsOptions = null, diff --git a/lib/src/layer/tile_provider/tile_provider.dart b/lib/src/layer/tile_provider/tile_provider.dart index be9bac443..ca4b353be 100644 --- a/lib/src/layer/tile_provider/tile_provider.dart +++ b/lib/src/layer/tile_provider/tile_provider.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:path/path.dart' as p; +import 'package:network_to_file_image/network_to_file_image.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_image/network.dart'; @@ -96,6 +98,29 @@ class FileTileProvider extends TileProvider { } } +class PersistentAdvancedCacheTileProvider extends TileProvider { + // Created by JaffaKetchup + @override + ImageProvider getImage(Coords coords, TileLayerOptions options) { + final Directory _appDocDirFolder = + Directory(options.saveDir.path + '/tiles/'); + if (!_appDocDirFolder.existsSync()) { + _appDocDirFolder.createSync(recursive: true); + } + return NetworkToFileImage( + url: getTileUrl(coords, options), + file: File( + p.join( + options.saveDir.path + '/tiles/', + getTileUrl(coords, options) + .replaceAll('https://', '') + .replaceAll('http://', '') + .replaceAll("/", "")), + ), + ); + } +} + class CustomTileProvider extends TileProvider { String Function(Coords coors, TileLayerOptions options) customTileUrl; diff --git a/pubspec.yaml b/pubspec.yaml index fa8335b10..35ad45cd2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,6 +23,7 @@ dependencies: vector_math: ^2.0.0 proj4dart: ^1.0.4 meta: ^1.1.0 + network_to_file_image: ^2.3.6 dev_dependencies: pedantic: ^1.8.0