Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 57 additions & 59 deletions flutter_map/lib/src/layer/tile_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:flutter_map/src/core/point.dart';
import 'package:flutter_map/src/map/map.dart';
import 'package:flutter_map/src/core/util.dart' as util;
import 'package:tuple/tuple.dart';
import 'package:quiver/core.dart';
import 'layer.dart';

class TileLayerOptions extends LayerOptions {
Expand Down Expand Up @@ -50,7 +51,6 @@ class _TileLayerState extends State<TileLayer>
Tuple2<double, double> _wrapX;
Tuple2<double, double> _wrapY;
double _tileZoom;
List<Widget> tiles = [];
Level _level;

Map<String, Tile> _tiles = {};
Expand All @@ -63,39 +63,16 @@ class _TileLayerState extends State<TileLayer>
..addListener(_handleFlingAnimation);
}

Widget createTile(Coords coords) {
var blankImageBytes = new Uint8List(0);
return new FadeInImage(
fadeInDuration: const Duration(milliseconds: 100),
key: new Key(_tileCoordsToKey(coords)),
// here `bytes` is a Uint8List containing the bytes for the in-memory image
placeholder: new MemoryImage(blankImageBytes),
image: new NetworkImage(getTileUrl(coords)),
fit: BoxFit.fill,
);
}

String getTileUrl(Coords coords) {
var data = <String, String>{
'x': coords.x.round().toString(),
'y': coords.y.round().toString(),
'z': _getZoomForUrl().round().toString(),
'z': coords.z.round().toString(),
};
var allOpts = new Map.from(data)..addAll(this.options.additionalOptions);
return util.template(this.options.urlTemplate, allOpts);
}

double _getZoomForUrl() {
var zoom = _tileZoom;
var maxZoom = options.maxZoom;
var zoomReverse = options.zoomReverse;
var zoomOffset = options.zoomOffset;
if (zoomReverse == true) {
zoom = maxZoom - zoom;
}
return zoom + zoomOffset;
}

void _resetView() {
this._setView(map.center, map.zoom);
}
Expand Down Expand Up @@ -124,9 +101,9 @@ class _TileLayerState extends State<TileLayer>
toRemove.add(z);
}
}

for (var z in toRemove) {
_removeTilesAtZoom(z);
_levels.remove(z);
}

var level = _levels[zoom];
Expand Down Expand Up @@ -184,7 +161,7 @@ class _TileLayerState extends State<TileLayer>
if (tile == null) {
return;
}
_tiles.remove(key);
_tiles[key].current = false;
}

_resetGrid() {
Expand Down Expand Up @@ -237,7 +214,6 @@ class _TileLayerState extends State<TileLayer>
return new Point(options.tileSize, options.tileSize);
}

// Gridlayer._update()
Widget build(BuildContext context) {
var pixelBounds = _getTiledPixelBounds(map.center);
var tileRange = _pxBoundsToTileRange(pixelBounds);
Expand All @@ -252,7 +228,6 @@ class _TileLayerState extends State<TileLayer>
}
}

// if the zoom level differs, call _setView to reset levels and prune old tiles...
_setView(map.center, map.zoom);

for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
Expand All @@ -269,18 +244,33 @@ class _TileLayerState extends State<TileLayer>
}
}

queue.sort((a, b) {
return (a.distanceTo(tileCenter) - b.distanceTo(tileCenter)).toInt();
});

const maxLength = 12;
var numExtraTiles = tiles.length - maxLength;
if (numExtraTiles < 0) numExtraTiles = 0;
tiles = tiles.sublist(numExtraTiles);
if (queue.length > 0) {
for (var i = 0; i < queue.length; i++) {
_addTile(queue[i]);
_tiles[_tileCoordsToKey(queue[i])] =
new Tile(_wrapCoords(queue[i]), true);
}
}

var tilesToRender = <Tile>[];
for (var tile in _tiles.values) {
if ((tile.coords.z - _level.zoom).abs() > 1) {
continue;
}
tilesToRender.add(tile);
}
tilesToRender.sort((aTile, bTile) {
var a = aTile.coords;
var b = bTile.coords;
// a = 13, b = 12, b is less than a, the result should be positive.
if (a.z != b.z) {
return (b.z - a.z).toInt();
}
return (a.distanceTo(tileCenter) - b.distanceTo(tileCenter)).toInt();
});

var tileWidgets = <Widget>[];
for (var tile in tilesToRender) {
tileWidgets.add(_createTileWidget(tile.coords));
}

return new GestureDetector(
Expand All @@ -289,7 +279,7 @@ class _TileLayerState extends State<TileLayer>
onScaleEnd: _handleScaleEnd,
child: new Container(
child: new Stack(
children: tiles,
children: tileWidgets,
),
color: Colors.grey[300],
),
Expand Down Expand Up @@ -417,33 +407,33 @@ class _TileLayerState extends State<TileLayer>
return "${coords.x}:${coords.y}:${coords.z}";
}

Widget _initTile(Widget tile, Coords coords, Point point) {
Widget _createTileWidget(Coords coords) {
var tilePos = _getTilePos(coords);
var level = _levels[coords.z];
var tileSize = getTileSize();
var pos = (point).multiplyBy(_level.scale) + _level.translatePoint;
var width = tileSize.x * _level.scale;
var height = tileSize.y * _level.scale;
var pos = (tilePos).multiplyBy(level.scale) + level.translatePoint;
var width = tileSize.x * level.scale;
var height = tileSize.y * level.scale;
var blankImageBytes = new Uint8List(0);

return new Positioned(
left: pos.x,
top: pos.y,
width: width,
height: height,
child: new Container(
child: tile,
child: new FadeInImage(
fadeInDuration: const Duration(milliseconds: 100),
key: new Key(_tileCoordsToKey(coords)),
// here `bytes` is a Uint8List containing the bytes for the in-memory image
placeholder: new MemoryImage(blankImageBytes),
image: new NetworkImage(getTileUrl(coords)),
fit: BoxFit.fill,
),
),
);
}

void _addTile(Coords coords) {
var tilePos = _getTilePos(coords);
var tile = createTile(_wrapCoords(coords));
tile = _initTile(tile, coords, tilePos);
var key = _tileCoordsToKey(coords);
_tiles[key] = new Tile(null, coords, true);
setState(() {
this.tiles.add(tile);
});
}

_wrapCoords(Coords coords) {
var newCoords = new Coords(
_wrapX != null
Expand All @@ -458,15 +448,15 @@ class _TileLayerState extends State<TileLayer>
}

Point _getTilePos(Coords coords) {
return coords.scaleBy(this.getTileSize()) - this._level.origin;
var level = _levels[coords.z];
return coords.scaleBy(this.getTileSize()) - level.origin;
}
}

class Tile {
final el;
final coords;
final Coords coords;
bool current;
Tile(this.el, this.coords, this.current);
Tile(this.coords, this.current);
}

class Level {
Expand All @@ -482,4 +472,12 @@ class Coords<T extends num> extends Point<T> {
T z;
Coords(T x, T y) : super(x, y);
String toString() => 'Coords($x, $y, $z)';
bool operator ==(other) {
if (other is Coords) {
return this.x == other.x && this.y == other.y && this.z == other.z;
}
return false;
}

int get hashCode => hash3(x, y, z);
}
1 change: 1 addition & 0 deletions flutter_map/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ dependencies:
sdk: flutter
latlong: ^0.4.0
tuple: ^1.0.0
quiver: ^0.28.0