Skip to content

Commit 88887b6

Browse files
committed
Cleanup and refactoring
Minor bug fixes Improved documentation
1 parent 1c23823 commit 88887b6

36 files changed

+314
-207
lines changed

example/lib/pages/home.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class _HomePageState extends State<HomePage> {
3838
initialZoom: 5,
3939
),
4040
children: [
41-
RasterTileLayer.simple(
41+
const RasterTileLayer.simple(
4242
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
4343
uaIdentifier: 'dev.fleaflet.flutter_map.demo',
4444
),

lib/flutter_map.dart

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,7 @@ export 'package:flutter_map/src/layer/attribution_layer/rich/widget.dart';
2929
export 'package:flutter_map/src/layer/attribution_layer/simple.dart';
3030
export 'package:flutter_map/src/layer/circle_layer/circle_layer.dart';
3131
export 'package:flutter_map/src/layer/marker_layer/marker_layer.dart';
32-
export 'package:flutter_map/src/layer/modern_tile_layer/source_generators/source_generator.dart';
33-
export 'package:flutter_map/src/layer/modern_tile_layer/source_generators/wms.dart';
34-
export 'package:flutter_map/src/layer/modern_tile_layer/source_generators/xyz.dart';
35-
export 'package:flutter_map/src/layer/modern_tile_layer/tile_layers/raster/tile_layer.dart';
36-
export 'package:flutter_map/src/layer/modern_tile_layer/tile_loader/bytes_fetchers/network/caching/built_in/built_in_caching_provider.dart';
37-
export 'package:flutter_map/src/layer/modern_tile_layer/tile_loader/bytes_fetchers/network/caching/caching_provider.dart';
38-
export 'package:flutter_map/src/layer/modern_tile_layer/tile_loader/bytes_fetchers/network/caching/disabled/disabled_caching_provider.dart';
39-
export 'package:flutter_map/src/layer/modern_tile_layer/tile_loader/bytes_fetchers/network/caching/tile_metadata.dart';
40-
export 'package:flutter_map/src/layer/modern_tile_layer/tile_loader/bytes_fetchers/network/caching/tile_read_failure_exception.dart';
32+
export 'package:flutter_map/src/layer/modern_tile_layer/modern_tile_layer.dart';
4133
export 'package:flutter_map/src/layer/overlay_image_layer/overlay_image_layer.dart';
4234
export 'package:flutter_map/src/layer/polygon_layer/label/deprecated_placements.dart';
4335
export 'package:flutter_map/src/layer/polygon_layer/label/placement_calculators/placement_calculator.dart';

lib/src/layer/modern_tile_layer/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ It does this by:
2222

2323
* using a canvas implementation for the default raster tile layer
2424

25-
Significant uestions remaining:
25+
Significant questions remaining:
2626

2727
* Is the default tile loader setup (with two stages) too much frameworking/overly-complicated?
2828
* Simulating retina mode affects all parts of the system - but only (conceptually/for reasoning) applies to raster tiles (although technically it's no different to a top layer option). How should this be represented?

lib/src/layer/modern_tile_layer/base_tile_data.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ class WrapperTileData<D extends Object?> implements BaseTileData {
5757
Future<D> get triggerPrune => _loadedTracker.future;
5858

5959
/// Whether [data] represents the loaded data
60-
@override
6160
bool get isLoaded => _loadedTracker.isCompleted;
6261

6362
@internal

lib/src/layer/modern_tile_layer/base_tile_layer.dart

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import 'dart:async';
2-
import 'dart:collection';
32

43
import 'package:flutter/widgets.dart';
54
import 'package:flutter_map/flutter_map.dart';
6-
import 'package:flutter_map/src/layer/modern_tile_layer/base_tile_data.dart';
7-
import 'package:flutter_map/src/layer/modern_tile_layer/options.dart';
8-
import 'package:flutter_map/src/layer/modern_tile_layer/tile_loader/tile_loader.dart';
95
import 'package:latlong2/latlong.dart';
6+
import 'package:logger/logger.dart';
107
import 'package:meta/meta.dart';
118

129
/// A map layer formed from adjacent square tiles loaded individually on demand
@@ -24,7 +21,6 @@ class BaseTileLayer<D extends BaseTileData> extends StatefulWidget {
2421
final Widget Function(
2522
BuildContext context,
2623
Object layerKey,
27-
TileLayerOptions options,
2824
Map<({TileCoordinates coordinates, Object layerKey}), D> visibleTiles,
2925
) renderer;
3026

@@ -52,6 +48,8 @@ class _BaseTileLayerState<D extends BaseTileData>
5248
if (oldWidget.options != widget.options ||
5349
oldWidget.tileLoader != widget.tileLoader ||
5450
oldWidget.renderer != widget.renderer) {
51+
// TODO: Remove
52+
Logger(printer: SimplePrinter()).d('Generating new `layerKey`');
5553
layerKey = UniqueKey();
5654
}
5755
}
@@ -102,8 +100,7 @@ class _BaseTileLayerState<D extends BaseTileData>
102100
return widget.renderer(
103101
context,
104102
layerKey,
105-
widget.options,
106-
Map.unmodifiable(tiles.map((k, v) => MapEntry(k, v._data))),
103+
Map.unmodifiable(tiles.map((k, v) => MapEntry(k, v.data))),
107104
);
108105
}
109106

@@ -239,28 +236,39 @@ typedef _TileKey = ({TileCoordinates coordinates, Object layerKey});
239236
extension type _TilesTracker<D extends BaseTileData>._(
240237
Map<_TileKey, _TileDataWithPrunableIndicator<D>> _map)
241238
implements Map<_TileKey, _TileDataWithPrunableIndicator<D>> {
242-
_TilesTracker()
243-
: this._(
244-
Map<_TileKey, _TileDataWithPrunableIndicator<D>>(
245-
/*(a, b) =>
246-
a.coordinates.z.compareTo(b.coordinates.z) |
247-
a.coordinates.x.compareTo(b.coordinates.x) |
248-
a.coordinates.y.compareTo(b.coordinates.y),*/
249-
),
250-
);
239+
_TilesTracker() : this._(<_TileKey, _TileDataWithPrunableIndicator<D>>{});
251240

241+
// ignore: experimental_member_use
252242
@redeclare
253-
D? remove(Object? key) => (_map.remove(key)?..dispose())?._data;
243+
void removeWhere(
244+
bool Function(_TileKey key, _TileDataWithPrunableIndicator<D> value) test,
245+
) {
246+
final keysToRemove = <_TileKey>[];
247+
for (final MapEntry(:key, :value) in _map.entries) {
248+
if (test(key, value)) keysToRemove.add(key);
249+
}
250+
for (final key in keysToRemove) {
251+
remove(key);
252+
}
253+
}
254+
255+
// ignore: experimental_member_use
256+
@redeclare
257+
D? remove(Object? key) {
258+
//print(StackTrace.current);
259+
return (_map.remove(key)?..dispose())?.data;
260+
}
254261
}
255262

256263
class _TileDataWithPrunableIndicator<D extends BaseTileData> {
257-
_TileDataWithPrunableIndicator(D data) : _data = data {
258-
_data.triggerPrune.then((_) => isPrunable = true);
264+
_TileDataWithPrunableIndicator(this.data) {
265+
data.triggerPrune.then((_) => isPrunable = true);
259266
}
260267

261-
final D _data;
262-
Future<void> get triggerPrune => _data.triggerPrune;
263-
void dispose() => _data.dispose();
268+
final D data;
269+
270+
Future<void> get triggerPrune => data.triggerPrune;
271+
void dispose() => data.dispose();
264272

265273
/// `true` when [BaseTileData.triggerPrune] has completed.
266274
///
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export 'base_tile_data.dart';
2+
export 'base_tile_layer.dart';
3+
export 'options.dart';
4+
export 'tile_layers/raster/raster.dart';
5+
export 'tile_loader/tile_loader.dart';
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import 'package:flutter/widgets.dart';
2+
import 'package:flutter_map/flutter_map.dart';
3+
4+
@immutable
5+
class RasterTileLayerOptions {
6+
const RasterTileLayerOptions({this.crs});
7+
8+
final Crs? crs;
9+
10+
@override
11+
bool operator ==(Object other) =>
12+
identical(this, other) ||
13+
(other is RasterTileLayerOptions && crs == other.crs);
14+
15+
@override
16+
int get hashCode => Object.hash(crs, null);
17+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export 'options.dart';
2+
export 'tile_layer.dart';
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
part of 'tile_layer.dart';
2+
3+
class _RasterRenderer extends StatefulWidget {
4+
_RasterRenderer({
5+
required Object layerKey,
6+
required this.visibleTiles,
7+
required this.options,
8+
required this.rasterOptions,
9+
}) : super(key: ValueKey(layerKey));
10+
11+
final Map<({TileCoordinates coordinates, Object layerKey}), RasterTileData>
12+
visibleTiles;
13+
final TileLayerOptions options;
14+
final RasterTileLayerOptions rasterOptions;
15+
16+
@override
17+
State<_RasterRenderer> createState() => __RasterRendererState();
18+
}
19+
20+
class __RasterRendererState extends State<_RasterRenderer> {
21+
late var _tileScaleCalculator = _generateTileScaleCalculator();
22+
TileScaleCalculator _generateTileScaleCalculator() => TileScaleCalculator(
23+
crs: widget.rasterOptions.crs ?? const Epsg3857(),
24+
tileDimension: widget.options.tileDimension,
25+
);
26+
27+
@override
28+
void didUpdateWidget(covariant _RasterRenderer oldWidget) {
29+
super.didUpdateWidget(oldWidget);
30+
31+
if (widget.rasterOptions.crs != oldWidget.rasterOptions.crs ||
32+
widget.options.tileDimension != oldWidget.options.tileDimension) {
33+
_tileScaleCalculator = _generateTileScaleCalculator();
34+
}
35+
}
36+
37+
@override
38+
Widget build(BuildContext context) {
39+
final map = MapCamera.of(context);
40+
41+
_tileScaleCalculator.clearCacheUnlessZoomMatches(map.zoom);
42+
43+
return MobileLayerTransformer(
44+
child: CustomPaint(
45+
size: Size.infinite,
46+
willChange: true,
47+
painter: _RasterPainter(
48+
options: widget.options,
49+
visibleTiles: widget.visibleTiles.entries.map(
50+
(tile) => (
51+
coordinates: tile.key.coordinates,
52+
scaledTileDimension: _tileScaleCalculator.scaledTileDimension(
53+
map.zoom,
54+
tile.key.coordinates.z,
55+
),
56+
currentPixelOrigin: map.pixelOrigin,
57+
data: tile.value,
58+
),
59+
),
60+
//tiles: tiles..sort(renderOrder),
61+
//tilePaint: widget.tilePaint,
62+
//tileOverlayPainter: widget.tileOverlayPainter,
63+
),
64+
),
65+
);
66+
}
67+
}
68+
69+
class _RasterPainter extends CustomPainter {
70+
final TileLayerOptions options;
71+
final Iterable<
72+
({
73+
TileCoordinates coordinates,
74+
double scaledTileDimension,
75+
Offset currentPixelOrigin,
76+
RasterTileData data
77+
})> visibleTiles;
78+
79+
_RasterPainter({
80+
super.repaint,
81+
required this.options,
82+
required this.visibleTiles,
83+
});
84+
85+
final Paint _basePaint = (null ?? Paint())
86+
..filterQuality = FilterQuality.high
87+
..isAntiAlias = true;
88+
89+
@override
90+
void paint(Canvas canvas, Size size) {
91+
for (final tile in visibleTiles) {
92+
if (tile.data.loaded?.successfulImageInfo?.image case final image?) {
93+
final origin = Offset(
94+
tile.coordinates.x * tile.scaledTileDimension -
95+
tile.currentPixelOrigin.dx,
96+
tile.coordinates.y * tile.scaledTileDimension -
97+
tile.currentPixelOrigin.dy,
98+
);
99+
100+
//final paint = _basePaint
101+
// ..color = (null?.color.withOpacity(tile.tileImage.opacity) ??
102+
// Color.fromRGBO(0, 0, 0, tile.tileImage.opacity));
103+
104+
canvas.drawImageRect(
105+
image,
106+
Offset.zero &
107+
Size(image.width.toDouble(), image.height.toDouble()), // src
108+
origin & Size.square(tile.scaledTileDimension), // dest
109+
_basePaint,
110+
);
111+
}
112+
}
113+
}
114+
115+
@override
116+
bool shouldRepaint(covariant CustomPainter oldDelegate) {
117+
return true;
118+
}
119+
}

0 commit comments

Comments
 (0)