|
1 | 1 | import 'dart:io'; |
2 | | -import 'dart:math'; |
3 | 2 |
|
4 | 3 | import 'package:flutter_map/flutter_map.dart' show LatLngBounds; |
5 | 4 | import 'package:flutter/foundation.dart' show visibleForTesting; |
6 | 5 |
|
7 | 6 | import '../offline_area_service.dart'; |
8 | 7 | import '../offline_areas/offline_area_models.dart'; |
| 8 | +import '../offline_areas/offline_tile_utils.dart' show latLonToTileRaw; |
9 | 9 | import '../../app_state.dart'; |
10 | 10 |
|
11 | 11 | /// Fetch a tile from the newest offline area that matches the given provider, or throw if not found. |
@@ -58,28 +58,21 @@ Future<List<int>> fetchLocalTile({ |
58 | 58 |
|
59 | 59 | /// O(1) check whether tile (z, x, y) falls within the given lat/lng bounds. |
60 | 60 | /// |
61 | | -/// Uses the same Mercator projection math as [latLonToTile] in |
62 | | -/// offline_tile_utils.dart, but only computes the bounding tile range |
63 | | -/// instead of enumerating every tile at that zoom level. |
| 61 | +/// Reuses [latLonToTileRaw] from offline_tile_utils.dart for the Mercator |
| 62 | +/// projection, computing only the bounding tile range instead of enumerating |
| 63 | +/// every tile at that zoom level. |
64 | 64 | /// |
65 | 65 | /// Note: Y axis is inverted in tile coordinates — north = lower Y. |
66 | 66 | @visibleForTesting |
67 | 67 | bool tileInBounds(LatLngBounds bounds, int z, int x, int y) { |
68 | | - final n = pow(2.0, z); |
69 | | - final west = bounds.west; |
70 | | - final east = bounds.east; |
71 | | - final north = bounds.north; |
72 | | - final south = bounds.south; |
| 68 | + final swTile = latLonToTileRaw(bounds.south, bounds.west, z); |
| 69 | + final neTile = latLonToTileRaw(bounds.north, bounds.east, z); |
73 | 70 |
|
74 | | - final minX = ((west + 180.0) / 360.0 * n).floor(); |
75 | | - final maxX = ((east + 180.0) / 360.0 * n).floor(); |
| 71 | + final minX = swTile[0].floor(); |
| 72 | + final maxX = neTile[0].floor(); |
76 | 73 | // North → lower Y (Mercator projection inverts latitude) |
77 | | - final minY = ((1.0 - log(tan(north * pi / 180.0) + |
78 | | - 1.0 / cos(north * pi / 180.0)) / |
79 | | - pi) / 2.0 * n).floor(); |
80 | | - final maxY = ((1.0 - log(tan(south * pi / 180.0) + |
81 | | - 1.0 / cos(south * pi / 180.0)) / |
82 | | - pi) / 2.0 * n).floor(); |
| 74 | + final minY = neTile[1].floor(); |
| 75 | + final maxY = swTile[1].floor(); |
83 | 76 |
|
84 | 77 | return x >= minX && x <= maxX && y >= minY && y <= maxY; |
85 | 78 | } |
|
0 commit comments