Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WMS and/or Tile layer animations #745

Closed
Swepilot opened this issue Sep 15, 2020 · 10 comments
Closed

WMS and/or Tile layer animations #745

Swepilot opened this issue Sep 15, 2020 · 10 comments

Comments

@Swepilot
Copy link

How would one go about creating an animation of several WMS and/or Tile layers? The use could e.g. be to show graphical weather data (satellite/radar) as it moves in time. Each layer would present the same type of data but from different points in time.

@maRci002
Copy link
Contributor

#583 / #745 asked for detect url changes, and PR #584 which is approved detects url changes so if you change TileLayerOptions' urlTemplate or WMSTileLayerOptions then it rerenders Tiles with new image. And there is PR #740 which is not merged but it detects additionalOptions changes.

The default behavior when url changed (for a moment map will be gray):

  • remove all current Tiles
  • start to load Tiles via new url

There is another behavior if you set overrideTilesWhenUrlChanges to true:

  • keep old Tile images on screen and start loading new ones
  • when a Tile is loaded then it will replace old one
  • it has tileFadeInStartWhenOverride option which can be between 0.0 - 1.0 so you can forinstance avoid load in opacity if you set it to 1.0

In summary you show one layer and change it's urlTemplate at runtime.

@Swepilot
Copy link
Author

@maRci002 thank you very much. I have been playing around a little with this and it looks like it could work for me. Am I correct in saying that e.g. #584 is only available in the git master branch and not in the 0.10.0 package? Currently I am relying on the new TileWidgetLayer that is available in 0.10.0

@maRci002
Copy link
Contributor

#584 avaible in 0.10.0

@Swepilot
Copy link
Author

I have now implemented the changing of urlTemplate at runtime and it works really well the first time a URL is loaded. Each new URL is loaded, creating a nice time lapse. However, when then looping backwards and re-using a URL that was loaded before, the layer is not visible on the map until I e.g. move the map by sliding it or something else causes the map to be re-drawn. It could be my not implementing setState properly, but it's confusing as it works well the first time... Any bright ideas?

@maRci002
Copy link
Contributor

Yes it is fixed with #715 in 0.10.1 (you have to upgrade) it was an annoying bug because I assumed onTileReady will be called async way, however if the image is in RAM then it will load sync way.

@Swepilot
Copy link
Author

I've upgraded to 0.10.1 but unfortunately that did not solve the problem. I'm using a FutureBuilder to build my TileLayerWidget. The Future contains information about which WMS layer to request. I have confirmed that the correct layer information is passed to the WMSTileLayerOptions . I think I have to create a new separate clean project to further debug this to make sure it's not something in my code that is the problem.

@maRci002
Copy link
Contributor

maRci002 commented Sep 25, 2020

I tested:

  • overrideTilesWhenUrlChange: false works fine
  • overrideTilesWhenUrlChange: true with tileFadeInStartWhenOverride: 0.0 works fine
  • overrideTilesWhenUrlChange: true with tileFadeInStartWhenOverride: 1.0 <- (special case) works fine

Here is my demo which covers all possibilities, change wms_tile_layer.dart to:

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';

import '../widgets/drawer.dart';

class WMSLayerPage extends StatefulWidget {
  static const String route = 'WMS layer';

  @override
  _WMSLayerPageState createState() => _WMSLayerPageState();
}

class _WMSLayerPageState extends State<WMSLayerPage> {
  final _layers = [
    's2cloudless-2018_3857',
    'overlay_base_bright_3857',
    'overlay_3857',
  ];

  var _counter = 0;

  var _overrideTilesWhenUrlChanges = false;
  var _tileFadeInStartWhenOverride = 0.0;

  void _changeLayer() {
    ++_counter;
    setState(() {});
  }

  void _changeOverrideMode() {
    _overrideTilesWhenUrlChanges = !_overrideTilesWhenUrlChanges;
    setState(() {});
  }

  void _changeFadeInStart() {
    _tileFadeInStartWhenOverride =
        _tileFadeInStartWhenOverride == 0.0 ? 1.0 : 0.0;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          FloatingActionButton(
            heroTag: 'Icons.layers',
            onPressed: _changeLayer,
            child: Icon(Icons.layers),
          ),
          SizedBox(height: 8),
          FloatingActionButton.extended(
            heroTag: 'Icons.flash_on',
            onPressed: _changeOverrideMode,
            icon: Icon(_overrideTilesWhenUrlChanges
                ? Icons.flash_off
                : Icons.flash_on),
            label: _overrideTilesWhenUrlChanges
                ? Text('Disable override')
                : Text('Enable override'),
          ),
          SizedBox(height: 8),
          FloatingActionButton.extended(
            heroTag: 'Icons.timelapse',
            backgroundColor: _overrideTilesWhenUrlChanges ? null : Colors.grey,
            onPressed: _overrideTilesWhenUrlChanges ? _changeFadeInStart : null,
            icon: Icon(_tileFadeInStartWhenOverride == 1.0
                ? Icons.timer_off
                : Icons.timelapse),
            label: Text(
                'Current fade start when override: $_tileFadeInStartWhenOverride'),
          ),
        ],
      ),
      appBar: AppBar(title: Text('WMS Layer')),
      drawer: buildDrawer(context, WMSLayerPage.route),
      body: Padding(
        padding: EdgeInsets.all(8.0),
        child: Column(
          children: [
            Padding(
              padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
              child: Text('This is a map that is showing (42.58, 12.43).'),
            ),
            Flexible(
              child: FlutterMap(
                options: MapOptions(
                  center: LatLng(42.58, 12.43),
                  zoom: 6.0,
                ),
                layers: [
                  TileLayerOptions(
                    wmsOptions: WMSTileLayerOptions(
                      baseUrl: 'https://{s}.s2maps-tiles.eu/wms/?',
                      layers: [_layers[_counter % 3]],
                    ),
                    tileFadeInDuration: 800,
                    subdomains: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
                    overrideTilesWhenUrlChanges: _overrideTilesWhenUrlChanges,
                    tileFadeInStartWhenOverride: _tileFadeInStartWhenOverride,
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Note: tileFadeInDuration: 800, just for easier catch to eyes.

@maRci002
Copy link
Contributor

If above code works but your code doesn't then change
https://github.com/fleaflet/flutter_map/blob/master/lib/src/layer/tile_layer.dart#L432
tile.loadTileImage(); to Timer.run(tile.loadTileImage); maybe it helps, your IDE will ask for confirmation to edit file say yes, then restart the app, and when you are done just press ctrl + Z or manually write back the original code snippet.

@Swepilot
Copy link
Author

Thank you very much, I got it working now. I cannot explain it, but in my case I had to set overrideTilesWhenUrlChanges: true for it to work. That's the behaviour I was looking for anyway to avoid having grey tiles between loads.

@maRci002
Copy link
Contributor

overrideTilesWhenUrlChanges: true and tileFadeInStartWhenOverride: 1.0 avoids grey tiles completely.

However the default behavior (overrideTilesWhenUrlChanges: false) should also work with #715 0.10.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants