Skip to content

Commit

Permalink
Reduce the tile management overhead. Sources:
Browse files Browse the repository at this point in the history
 * Don't compute hash of hashes.
 * Cache the hash
 * Use hash as key and avoid string interpolation.

Also as a drive-by get rid of the TileCoordinates extends Point + zoom
coordinate in favor of more consistent composition.
  • Loading branch information
ignatz committed Oct 27, 2023
1 parent c24b6e6 commit 10e1b52
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 20 deletions.
11 changes: 5 additions & 6 deletions lib/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,11 @@ class WrappedTileBoundsAtZoom extends TileBoundsAtZoom {
}

bool _wrappedBothContains(TileCoordinates coordinates) {
return tileRange.contains(
Point(
_wrapInt(coordinates.x, wrapX!),
_wrapInt(coordinates.y, wrapY!),
),
);
return tileRange.contains(TileCoordinates(
_wrapInt(coordinates.x, wrapX!),
_wrapInt(coordinates.y, wrapY!),
coordinates.z,
));
}

bool _wrappedXInRange(TileCoordinates coordinates) {
Expand Down
18 changes: 13 additions & 5 deletions lib/src/layer/tile_layer/tile_coordinates.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,33 @@ import 'dart:math';
import 'package:meta/meta.dart';

@immutable
class TileCoordinates extends Point<int> {
class TileCoordinates {
final int x;
final int y;
final int z;

const TileCoordinates(super.x, super.y, this.z);
int? _hashCode;

String get key => '$x:$y:$z';
TileCoordinates(this.x, this.y, this.z);

//int get key => ((x & 0xffff) << (20)) | ((y & 0xffff) << 8) | (z & 0xff);
int get key => hashCode;

@override
String toString() => 'TileCoordinate($x, $y, $z)';

// Overridden because Point's distanceTo does not allow comparing with a point
// of a different type.
@override
double distanceTo(Point<num> other) {
final dx = x - other.x;
final dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}

Point scaleBy(Point p) {
return Point(x * p.x, y * p.y);
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
Expand All @@ -32,5 +40,5 @@ class TileCoordinates extends Point<int> {
}

@override
int get hashCode => Object.hash(x.hashCode, y.hashCode, z.hashCode);
int get hashCode => _hashCode ??= Object.hash(x, y, z);
}
2 changes: 1 addition & 1 deletion lib/src/layer/tile_layer/tile_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class TileImage extends ChangeNotifier {

AnimationController? get animation => _animationController;

String get coordinatesKey => coordinates.key;
int get coordinatesKey => coordinates.key;

/// Whether the tile is displayable. This means that either:
/// * Loading errored but an error image is configured.
Expand Down
8 changes: 4 additions & 4 deletions lib/src/layer/tile_layer/tile_image_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ typedef TileCreator = TileImage Function(TileCoordinates coordinates);

@immutable
class TileImageManager {
final Map<String, TileImage> _tiles = {};
final Map<int, TileImage> _tiles = {};

bool containsTileAt(TileCoordinates coordinates) =>
_tiles.containsKey(coordinates.key);
Expand Down Expand Up @@ -83,7 +83,7 @@ class TileImageManager {
/// All removals should be performed by calling this method to ensure that
// disposal is performed correctly.
void _remove(
String key, {
int key, {
required bool Function(TileImage tileImage) evictImageFromCache,
}) {
final removed = _tiles.remove(key);
Expand All @@ -94,7 +94,7 @@ class TileImageManager {
}

void _removeWithEvictionStrategy(
String key,
int key,
EvictErrorTileStrategy strategy,
) {
_remove(
Expand All @@ -105,7 +105,7 @@ class TileImageManager {
}

void removeAll(EvictErrorTileStrategy evictStrategy) {
final keysToRemove = List<String>.from(_tiles.keys);
final keysToRemove = List<int>.from(_tiles.keys);

for (final key in keysToRemove) {
_removeWithEvictionStrategy(key, evictStrategy);
Expand Down
4 changes: 2 additions & 2 deletions lib/src/layer/tile_layer/tile_image_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import 'package:flutter_map/src/layer/tile_layer/tile_image.dart';
import 'package:flutter_map/src/layer/tile_layer/tile_range.dart';

class TileImageView {
final Map<String, TileImage> _tileImages;
final Map<int, TileImage> _tileImages;
final DiscreteTileRange _visibleRange;
final DiscreteTileRange _keepRange;

TileImageView({
required Map<String, TileImage> tileImages,
required Map<int, TileImage> tileImages,
required DiscreteTileRange visibleRange,
required DiscreteTileRange keepRange,
}) : _tileImages = UnmodifiableMapView(tileImages),
Expand Down
10 changes: 8 additions & 2 deletions lib/src/layer/tile_layer/tile_range.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,14 @@ class DiscreteTileRange extends TileRange {
);
}

bool contains(Point<int> point) {
return _bounds.contains(point);
bool contains(TileCoordinates point) {
if (zoom != point.z) {
return false;
}
return (point.x >= _bounds.min.x) &&
(point.x <= _bounds.max.x) &&
(point.y >= _bounds.min.y) &&
(point.y <= _bounds.max.y);
}

Point<int> get min => _bounds.min;
Expand Down

0 comments on commit 10e1b52

Please sign in to comment.