Tile Loading Interceptor

To track (eg. for debugging and logging) the internal tile loading mechanisms, FMTCTileProvider.tileLoadingInterceptor may be used.

For example, this could be used to debug why tiles aren't loading as expected (perhaps in combination with TileLayer.tileBuilder & ValueListenableBuilder as in the example app & below), or to perform more advanced monitoring and logging (than the hit & miss statistics provide).

The interceptor uses a ValueNotifier, which allows FMTC internals to notify & push updates of tile loads, and allows the owner to listen for changes as well as retrieve the latest update (value) immediately.

The object within the ValueNotifier is a mapping of TileCoordinates to TileLoadingInterceptorResults. These result objects contain multiple fields, which can be explored in the Full API Documentation:

link

Example

See the following example, which demonstrates how to listen directly to it, and how to use it in combination with a custom tileBuilder using a ValueListenableBuilder to listen to it in a widget tree.

// Widget definition omitted

class _InterceptedMapState extends State<InterceptedMap> {
  final _tileLoadingInterceptor = ValueNotifier<TileLoadingInterceptorMap>({});

  // Listen directly
  void _tileLoadingInterceptorListener() {
    print('New tile loaded! Full map of results:');
    print(_tileLoadingInterceptor.value);
  }

  @override
  void initState() {
    super.initState();
    _tileLoadingInterceptor.addListener(_tileLoadingInterceptorListener);
  }

  @override
  void dispose() {
    _tileLoadingInterceptor.removeListener(_tileLoadingInterceptorListener);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FlutterMap(
      // options: MapOptions(),
      children: [
        TileLayer(
          tileProvider: FMTCTileProvider.multipleStores(
            storeNames: {}, // TODO: specify stores
            tileLoadingInterceptor: _tileLoadingInterceptor,
          ),
          tileBuilder: (context, tileWidget, tile) {
            return Stack(
              fit: StackFit.expand,
              children: [
                tileWidget,
                Center(
                  // Listen in the widget tree
                  child: ValueListenableBuilder(
                    valueListenable: _tileLoadingInterceptor,
                    builder: (context, result, _) => Text(
                      // Get the current tile result 'path'
                      result[tile.coordinates]?.resultPath?.toString() ??
                          'Not loaded',
                    ),
                  ),
                ),
              ],
            );
          },
        ),
      ],
    );
  }
}

Last updated

© Luka Stillingfleet (JaffaKetchup)