Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support caching of
VectorTileFeature
s resolved for a `ThemeLa…
…yer`
- Loading branch information
Showing
7 changed files
with
210 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import '../../vector_tile_renderer.dart'; | ||
import 'theme_layers.dart'; | ||
|
||
/// Resolver for resolving the [VectorTileFeature]s a [ThemeLayer] should | ||
/// render. | ||
abstract class ThemeLayerFeatureResolver { | ||
/// Resolves and returns the [VectorTileFeature]s within the given [tileset] | ||
/// that the given [themeLayer] should render. | ||
Iterable<ResolvedThemeLayerFeature> resolveFeatures(DefaultLayer themeLayer); | ||
} | ||
|
||
/// Default implementation of [ThemeLayerFeatureResolver]. | ||
class DefaultThemeLayerFeatureResolver implements ThemeLayerFeatureResolver { | ||
DefaultThemeLayerFeatureResolver(this.tileset); | ||
|
||
final Tileset tileset; | ||
|
||
@override | ||
Iterable<ResolvedThemeLayerFeature> resolveFeatures( | ||
DefaultLayer themeLayer, | ||
) sync* { | ||
for (final layer in themeLayer.selector.select(tileset)) { | ||
for (final feature | ||
in themeLayer.selector.layerSelector.features(layer.features)) { | ||
yield ResolvedThemeLayerFeature(layer, feature); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// A [ThemeLayerFeatureResolver] that uses another [resolver] and caches | ||
/// its results. | ||
class CachingThemeLayerFeatureResolver implements ThemeLayerFeatureResolver { | ||
CachingThemeLayerFeatureResolver(this.resolver); | ||
|
||
/// The resolver whose results will be cached. | ||
final ThemeLayerFeatureResolver resolver; | ||
|
||
final _cache = <DefaultLayer, List<ResolvedThemeLayerFeature>>{}; | ||
|
||
@override | ||
Iterable<ResolvedThemeLayerFeature> resolveFeatures(DefaultLayer themeLayer) { | ||
return _cache.putIfAbsent( | ||
themeLayer, | ||
() => resolver.resolveFeatures(themeLayer).toList(), | ||
); | ||
} | ||
} | ||
|
||
/// Wrapper around [VectorTileFeature] that includes the containing | ||
/// [VectorTileLayer]. | ||
class ResolvedThemeLayerFeature { | ||
ResolvedThemeLayerFeature(this.layer, this.feature); | ||
|
||
final VectorTileLayer layer; | ||
final VectorTileFeature feature; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,4 +13,5 @@ dependencies: | |
vector_tile: ^0.3.0 | ||
|
||
dev_dependencies: | ||
benchmark_harness: ^2.0.0 | ||
test: ^1.17.5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import 'dart:ui'; | ||
|
||
import 'package:benchmark_harness/benchmark_harness.dart'; | ||
import 'package:vector_tile_renderer/src/constants.dart'; | ||
import 'package:vector_tile_renderer/src/themes/light_theme.dart'; | ||
import 'package:vector_tile_renderer/vector_tile_renderer.dart'; | ||
|
||
import '../src/test_tile.dart'; | ||
|
||
Picture _renderPicture({ | ||
required Theme theme, | ||
required double scale, | ||
required Tileset tileset, | ||
required double zoom, | ||
}) { | ||
assert(scale >= 1 && scale <= 4); | ||
|
||
double size = scale * tileSize; | ||
final rect = Rect.fromLTRB(0, 0, size, size); | ||
|
||
final recorder = PictureRecorder(); | ||
final canvas = Canvas(recorder, rect); | ||
canvas.clipRect(rect); | ||
canvas.scale(scale.toDouble(), scale.toDouble()); | ||
|
||
Renderer(theme: theme).render( | ||
canvas, | ||
tileset, | ||
zoomScaleFactor: scale, | ||
zoom: zoom, | ||
); | ||
|
||
return recorder.endRecording(); | ||
} | ||
|
||
class RenderPicture extends BenchmarkBase { | ||
RenderPicture({ | ||
required this.zoom, | ||
this.preprocessTile = false, | ||
this.preprocessThemeLayerFeatures = false, | ||
}) : super('RenderPicture(' | ||
'zoom: $zoom, ' | ||
'preprocessTile: $preprocessTile, ' | ||
'preprocessThemeLayerFeatures: $preprocessThemeLayerFeatures' | ||
')'); | ||
|
||
static Future<void> setupAll() async { | ||
testTile = await readTestTile(); | ||
} | ||
|
||
static late final VectorTile testTile; | ||
|
||
final double zoom; | ||
final bool preprocessTile; | ||
final bool preprocessThemeLayerFeatures; | ||
|
||
late final Theme theme; | ||
late final Tileset tileset; | ||
|
||
@override | ||
void setup() { | ||
theme = ThemeReader().read(lightThemeData()); | ||
final tileset = Tileset({'openmaptiles': testTile}); | ||
|
||
this.tileset = preprocessTile | ||
? TilesetPreprocessor(theme).preprocess( | ||
tileset, | ||
themeLayerFeatures: preprocessThemeLayerFeatures, | ||
) | ||
: tileset; | ||
} | ||
|
||
@override | ||
void run() => _renderPicture( | ||
theme: theme, | ||
tileset: tileset, | ||
scale: 1, | ||
zoom: zoom, | ||
); | ||
} | ||
|
||
Future<void> main() async { | ||
await RenderPicture.setupAll(); | ||
|
||
final benchmarks = [ | ||
for (final zoom in <double>[0, 12, 24]) ...[ | ||
RenderPicture(zoom: zoom, preprocessTile: false), | ||
RenderPicture(zoom: zoom, preprocessTile: true), | ||
RenderPicture( | ||
zoom: zoom, | ||
preprocessTile: false, | ||
preprocessThemeLayerFeatures: false, | ||
), | ||
RenderPicture( | ||
zoom: zoom, | ||
preprocessTile: true, | ||
preprocessThemeLayerFeatures: true, | ||
), | ||
] | ||
]; | ||
|
||
for (final benchmark in benchmarks) { | ||
benchmark.report(); | ||
} | ||
} |