| | 1 | | using System; |
| | 2 | | using System.Collections; |
| | 3 | | using System.Collections.Generic; |
| | 4 | |
|
| | 5 | | namespace Itinero.IO.Osm.Tiles; |
| | 6 | |
|
| | 7 | | internal struct TileRange : IEnumerable<Tile> |
| | 8 | | { |
| | 9 | | public TileRange( |
| | 10 | | ((double longitude, double latitude, float? e) topLeft, (double longitude, double latitude, float? e) |
| | 11 | | bottomRight) box, int zoom) |
| 0 | 12 | | { |
| 0 | 13 | | var topLeft = Tile.WorldToTile(box.topLeft.longitude, box.topLeft.latitude, zoom); |
| 0 | 14 | | var bottomRight = Tile.WorldToTile(box.bottomRight.longitude, box.bottomRight.latitude, zoom); |
| | 15 | |
|
| 0 | 16 | | this.Left = topLeft.X; |
| 0 | 17 | | this.Top = topLeft.Y; |
| 0 | 18 | | this.Right = bottomRight.X; |
| 0 | 19 | | this.Bottom = bottomRight.Y; |
| 0 | 20 | | this.Zoom = zoom; |
| | 21 | |
|
| 0 | 22 | | if (this.Top > this.Bottom) |
| 0 | 23 | | { |
| 0 | 24 | | throw new ArgumentException("Invalid tile range, top is lower than bottom."); |
| | 25 | | } |
| 0 | 26 | | } |
| | 27 | |
|
| 0 | 28 | | public uint Left { get; } |
| | 29 | |
|
| 0 | 30 | | public uint Right { get; } |
| | 31 | |
|
| 0 | 32 | | public uint Top { get; } |
| | 33 | |
|
| 0 | 34 | | public uint Bottom { get; } |
| | 35 | |
|
| 0 | 36 | | public int Zoom { get; } |
| | 37 | |
|
| | 38 | | public IEnumerator<Tile> GetEnumerator() |
| 0 | 39 | | { |
| 0 | 40 | | return new TileRangeEnumerator(this); |
| 0 | 41 | | } |
| | 42 | |
|
| | 43 | | IEnumerator IEnumerable.GetEnumerator() |
| 0 | 44 | | { |
| 0 | 45 | | return this.GetEnumerator(); |
| 0 | 46 | | } |
| | 47 | |
|
| | 48 | | private struct TileRangeEnumerator : IEnumerator<Tile> |
| | 49 | | { |
| | 50 | | private readonly TileRange _tileRange; |
| | 51 | |
|
| | 52 | | public TileRangeEnumerator(TileRange tileRange) |
| 0 | 53 | | { |
| 0 | 54 | | _tileRange = tileRange; |
| 0 | 55 | | _x = uint.MaxValue; |
| 0 | 56 | | _y = uint.MaxValue; |
| 0 | 57 | | } |
| | 58 | |
|
| | 59 | | private uint _x; |
| | 60 | | private uint _y; |
| | 61 | |
|
| | 62 | | public bool MoveNext() |
| 0 | 63 | | { |
| 0 | 64 | | if (_x == uint.MaxValue) |
| 0 | 65 | | { |
| 0 | 66 | | _x = _tileRange.Left; |
| 0 | 67 | | _y = _tileRange.Top; |
| 0 | 68 | | return true; |
| | 69 | | } |
| | 70 | |
|
| 0 | 71 | | if (_tileRange.Left > _tileRange.Right) |
| 0 | 72 | | { // not supported. |
| 0 | 73 | | throw new Exception("Tile ranges crossing date line not supported."); |
| | 74 | | } |
| | 75 | |
|
| 0 | 76 | | if (_x == _tileRange.Right) |
| 0 | 77 | | { // move y. |
| 0 | 78 | | if (_y == _tileRange.Bottom) |
| 0 | 79 | | { // enumeration finished. |
| 0 | 80 | | return false; |
| | 81 | | } |
| | 82 | |
|
| 0 | 83 | | _y++; |
| 0 | 84 | | _x = _tileRange.Left; |
| 0 | 85 | | return true; |
| | 86 | | } |
| | 87 | |
|
| 0 | 88 | | _x++; |
| 0 | 89 | | return true; |
| 0 | 90 | | } |
| | 91 | |
|
| | 92 | | public void Reset() |
| 0 | 93 | | { |
| 0 | 94 | | _x = uint.MaxValue; |
| 0 | 95 | | _y = uint.MaxValue; |
| 0 | 96 | | } |
| | 97 | |
|
| 0 | 98 | | public Tile Current => new(_x, _y, _tileRange.Zoom); |
| | 99 | |
|
| 0 | 100 | | object IEnumerator.Current => this.Current; |
| | 101 | |
|
| 0 | 102 | | public void Dispose() { } |
| | 103 | | } |
| | 104 | | } |