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

Feature: Post process tiles #582

Merged
merged 7 commits into from Mar 16, 2021

Conversation

matthiasdittmer
Copy link
Contributor

See #581

@johnpryan
Copy link
Collaborator

It might be better to provide a TileBuilder API instead, where the builder is called for each Tile.

@matthiasdittmer
Copy link
Contributor Author

It might be better to provide a TileBuilder API instead, where the builder is called for each Tile.

Maybe someone can clarify this for me. I do not understand TileBuilder API (?).

I would like to have this feature merged.

@maRci002
Copy link
Contributor

maRci002 commented Aug 24, 2020

TileBuilder API means:

define custom function, here we pass tileWidget and tile too because we can read properties like tile.loadError:

typedef TileBuilder = Widget Function(Widget tileWidget, Tile tile);

define a defaultbuilder which just returns tileWidget

Widget _defaultTileBuilder(Widget tileWidget, Tile tile) => tileWidget;

In TileLayerOptions:

class TileLayerOptions extends LayerOptions {
    ...
    // TODO: create some doc where you can write an example
    final TileBuilder tileBuilder;

    TileLayerOptions({
        ....
        this.tileBuilder = _defaultTileBuilder,
        rebuild,
      }) ....
}

In AnimatedTile (don't forget to pass tileBuilder in _createTileWidget: tileBuilder: options.tileBuilder, ):

class AnimatedTile extends StatefulWidget {
  final Tile tile;
  final ImageProvider errorImage;
  final TileBuilder tileBuilder;

  AnimatedTile(
      {Key key, @required this.tile, this.errorImage, @required this.tileBuilder})

In _AnimatedTileState:

  @override
  Widget build(BuildContext context) {
    final tileWidget = (widget.tile.loadError && widget.errorImage != null)
        ? Image(
            image: widget.errorImage,
            fit: BoxFit.fill,
          )
        : RawImage(
            image: widget.tile.imageInfo?.image,
            fit: BoxFit.fill,
          );

    return Opacity(
      opacity: widget.tile.opacity,
      child: widget.tileBuilder(tileWidget, widget.tile), // Here is our tile builder
    );
  }

And finally we can pass our builder to TileLayerOptions like this:

TileLayerOptions(
  urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
  subdomains: ['a', 'b', 'c'],
  tileBuilder: (Widget tileWidget, Tile tile) {
    if (tile.loadError) {
        // apply red colorFilter or wrap widget with another custom Widget
    }

    return ColorFiltered(
        colorFilter: const ColorFilter.matrix(<double>[
                -1,  0,  0, 0, 255,
                0, -1,  0, 0, 255,
                0,  0, -1, 0, 255,
                0,  0,  0, 1,   0,
        ]),
        child: tileWidget);
  },
);

I know currently you apply colorFilter around tileWidgets' Container but applying colorFilter to each tile works too however you can do a secondary builder around Container forexample:

typedef TilesContainerBuilder = Widget Function(Widget container, List<Tile> tiles);
Widget _defaultTilesContainerBuilder(Widget container, List<Tile> tiles) => container;

I think in this PR you can implement both tileBuilder and tilesContainerBuilder functions.

@maRci002
Copy link
Contributor

Or maybe tileBuilder can be null so _defaultTileBuilder not needed and when you see it is null then just return tileWidget instead of calling it (eliminates error when programmer passes explicit nullto tileBuilder). And you can create a custom dart file for predefined TileBuilders where you can store darkModeTileBuilder function so in doc you can mention there are predefined ones try them out.

@matthiasdittmer
Copy link
Contributor Author

Or maybe tileBuilder can be null so _defaultTileBuilder not needed and when you see it is null then just return tileWidget instead of calling it (eliminates error when programmer passes explicit nullto tileBuilder). And you can create a custom dart file for predefined TileBuilders where you can store darkModeTileBuilder function so in doc you can mention there are predefined ones try them out.

@maRci002 I see you did the work already in your head. You could also push on this PR.

@maRci002
Copy link
Contributor

@mat8854 I think I cannot push to this PR however I can fork your fork and make pull request to your fork's branch. It would be nice if you could update your master because first step I'll make the branch up to with master.

@matthiasdittmer
Copy link
Contributor Author

@mat8854 I think I cannot push to this PR however I can fork your fork and make pull request to your fork's branch. It would be nice if you could update your master because first step I'll make the branch up to with master.

@maRci002 Okay, only maintainers can do that. It worked with another repo.

@ThexXTURBOXx
Copy link
Contributor

@mat8854 I have updated your commit to the current master branch here: https://github.com/Femtopedia/flutter_map

I could PR it into your repo, so you can update your branch, if you want.

@DrNorton
Copy link

@mat8854 @maRci002 Hello! Is there any update on that feature? Really need TileBuilder API functionality. Is there possibility to get it any time soon?

@maRci002
Copy link
Contributor

@DrNorton yes today I'll make a PR to @mat8854 's branch. I've some cool default TileBuilder functions in my mind.

@maRci002
Copy link
Contributor

maRci002 commented Sep 16, 2020

@mat8854 I made a PR to your fork, check it out.

I think if you approve changes then changes also appears here, there isn't any rebase.

tile_builder

@matthiasdittmer
Copy link
Contributor Author

@maRci002 Thank you, I approved your changes on my branch. They are now also visible here.

@ThexXTURBOXx @DrNorton Note the new changes.

@johnpryan
Copy link
Collaborator

@mat8854 can you take a look at the build and see if you can fix it?

@maRci002
Copy link
Contributor

maRci002 commented Sep 16, 2020

Idk but my PR builds also fails.
I think mixing package and relative imports may cause wierd errrors in Dart.

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

import '../widgets/drawer.dart'; // this should be also package import!

@mat8854 can you eliminate all relative imports from project maybe it helps?
Just search for import '. text in project and in Android Studio and press Alt + Enter -> convert to 'package:' import
image

@johnpryan
Copy link
Collaborator

johnpryan commented Sep 16, 2020

It's okay to use relative imports. In this case it looks like a problem with the example:

The command "~/flutter/bin/flutter packages get" exited with 0.
18.57s$ ~/flutter/bin/cache/dart-sdk/bin/dartanalyzer .
Analyzing flutter_map...
  error • Target of URI doesn't exist: 'package:flutter_map_example/pages/tile_builder_example.dart'. • example/lib/main.dart:2:8 • uri_does_not_exist
  error • Undefined name 'TileBuilderPage'. • example/lib/main.dart:62:9 • undefined_identifier
  error • The method 'TileBuilderPage' isn't defined for the type 'MyApp'. • example/lib/main.dart:62:45 • undefined_method
  error • Target of URI doesn't exist: 'package:flutter_map_example/pages/tile_builder_example.dart'. • example/lib/widgets/drawer.dart:2:8 • uri_does_not_exist
  error • Undefined name 'TileBuilderPage'. • example/lib/widgets/drawer.dart:188:11 • undefined_identifier
5 errors found.
The command "~/flutter/bin/cache/dart-sdk/bin/dartanalyzer ." exited with 3.

@maRci002
Copy link
Contributor

maRci002 commented Sep 16, 2020

flutter_map.dart exports export 'package:flutter_map/src/layer/tile_builder/tile_builder.dart';

And tile_builder.dart imports import 'package:flutter_map/flutter_map.dart';

This causes the error?

@maRci002 maRci002 mentioned this pull request Sep 17, 2020
@maRci002
Copy link
Contributor

maRci002 commented Sep 18, 2020

@johnpryan for me 200400f and 239c151 fixed the problem. So mixing relative and package imports may cause wierd bugs in Dart. I think the best pattern is to only use package imports. Plot twist IDE's and manual dartanalyzer don't show these errors.

I'll update this PR imports too. Edit: matthiasdittmer#4 this should fix the problem

@matthiasdittmer
Copy link
Contributor Author

@johnpryan @maRci002 Travis is passing now.

@johnpryan johnpryan merged commit 1d660b2 into fleaflet:master Mar 16, 2021
@maRci002 maRci002 mentioned this pull request Mar 18, 2021
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

Successfully merging this pull request may close these issues.

None yet

6 participants