Skip to content

Commit

Permalink
Merge branch 'main' into drift
Browse files Browse the repository at this point in the history
  • Loading branch information
JaffaKetchup authored Feb 3, 2025
2 parents 32a1770 + 77bd6da commit b9f94ae
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 202 deletions.
22 changes: 0 additions & 22 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,6 @@ concurrency:
cancel-in-progress: true

jobs:
score-package:
name: "Score Package"
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Run Dart Package Analyser
uses: axel-op/dart-package-analyzer@master
id: analysis
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Check Package Scores
env:
TOTAL: ${{ steps.analysis.outputs.total }}
TOTAL_MAX: ${{ steps.analysis.outputs.total_max }}
run: |
if (( $TOTAL < $TOTAL_MAX ))
then
echo Package score less than available score. Improve the score!
exit 1
fi
analyse-code:
name: "Analyse Code"
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Many thanks to my sponsors, no matter how much or how little they donated. Spons

# Changelog

## [10.1.0] - 2025/02/02

* Added support for flutter_map v8

## [10.0.0] - "Better Browsing" - 2025/01/11

This update builds on v9 to fully embrace the new many-to-many relationship between tiles and stores, which allows for more flexibility when constructing the `FMTCTileProvider`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@ class _DownloadProgressMaskerRenderer extends RenderProxyBox {

/// Project specified coordinates to a screen space [Rect]
Rect _calculateRectOfCoords(LatLng nwCoord, LatLng seCoord) {
final nwScreen = mapCamera.latLngToScreenPoint(nwCoord);
final seScreen = mapCamera.latLngToScreenPoint(seCoord);
return Rect.fromPoints(nwScreen.toOffset(), seScreen.toOffset());
final nwScreen = mapCamera.latLngToScreenOffset(nwCoord);
final seScreen = mapCamera.latLngToScreenOffset(seCoord);
return Rect.fromPoints(nwScreen, seScreen);
}

/// Handles incoming tiles from the input stream, modifying the [_tileMapping]
Expand Down Expand Up @@ -272,9 +272,20 @@ class _DownloadProgressMaskerRenderer extends RenderProxyBox {
} else {
final zoom = tile.z.toDouble();
_tileMapping[intermediateZoomTile] = tmv = _TileMappingValue.newTile(
nwCoord: mapCamera.crs.pointToLatLng(tile * tileSize, zoom),
seCoord: mapCamera.crs
.pointToLatLng((tile + const Point(1, 1)) * tileSize, zoom),
nwCoord: mapCamera.crs.offsetToLatLng(
Offset(
(tile.x * tileSize).toDouble(),
(tile.y * tileSize).toDouble(),
),
zoom,
),
seCoord: mapCamera.crs.offsetToLatLng(
Offset(
((tile.x + 1) * tileSize).toDouble(),
((tile.y + 1) * tileSize).toDouble(),
),
zoom,
),
);
_mostRecentTile =
() => _calculateRectOfCoords(tmv.nwCoord, tmv.seCoord);
Expand Down
9 changes: 3 additions & 6 deletions example/lib/src/screens/main/map_view/map_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ class _MapViewState extends State<MapView> with TickerProviderStateMixin {
final coords = provider.currentConstructingCoordinates;
if (coords.length > 1) {
final newPointPos = _mapController.mapController.camera
.latLngToScreenPoint(coords.first)
.toOffset();
.latLngToScreenOffset(coords.first);
provider.customPolygonSnap = coords.first != coords.last &&
sqrt(
pow(newPointPos.dx - evt.localPosition.dx, 2) +
Expand All @@ -196,11 +195,9 @@ class _MapViewState extends State<MapView> with TickerProviderStateMixin {
final coords = provider.currentConstructingCoordinates;
if (coords.length > 1) {
final newPointPos = _mapController.mapController.camera
.latLngToScreenPoint(coords.first)
.toOffset();
.latLngToScreenOffset(coords.first);
final centerPos = _mapController.mapController.camera
.latLngToScreenPoint(provider.currentNewPointPos!)
.toOffset();
.latLngToScreenOffset(provider.currentNewPointPos!);
provider.customPolygonSnap = coords.first != coords.last &&
sqrt(
pow(newPointPos.dx - centerPos.dx, 2) +
Expand Down
6 changes: 2 additions & 4 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: fmtc_demo
description: The demo app for 'flutter_map_tile_caching', showcasing its functionality and use-cases.
publish_to: "none"
version: 10.0.0
version: 10.1.0

environment:
sdk: ">=3.6.0 <4.0.0"
Expand Down Expand Up @@ -33,9 +33,7 @@ dependencies:

dependency_overrides:
flutter_map:
git:
url: https://github.com/fleaflet/flutter_map.git
ref: d816b4d54f9245e260b125ea1adbf300b5c39843
git: https://github.com/fleaflet/flutter_map.git
flutter_map_tile_caching:
path: ../

Expand Down
139 changes: 74 additions & 65 deletions lib/src/bulk_download/internal/tile_loops/count.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,17 @@ class TileCounters {
for (double zoomLvl = region.minZoom.toDouble();
zoomLvl <= region.maxZoom;
zoomLvl++) {
final nwPoint = (region.crs.latLngToPoint(northWest, zoomLvl) /
region.options.tileSize)
.floor();
final sePoint = (region.crs.latLngToPoint(southEast, zoomLvl) /
region.options.tileSize)
.ceil() -
const Point(1, 1);

tileCount += (sePoint.x - nwPoint.x + 1) * (sePoint.y - nwPoint.y + 1);
final scaleLvl = region.crs.scale(zoomLvl);

final nw = region.crs.latLngToXY(northWest, scaleLvl);
final nwX = (nw.$1 / region.options.tileDimension).floor();
final nwY = (nw.$2 / region.options.tileDimension).floor();

final se = region.crs.latLngToXY(southEast, scaleLvl);
final seX = (se.$1 / region.options.tileDimension).ceil() - 1;
final seY = (se.$2 / region.options.tileDimension).ceil() - 1;

tileCount += (seX - nwX + 1) * (seY - nwY + 1);
}

return _trimToRange(region, tileCount);
Expand All @@ -64,20 +66,19 @@ class TileCounters {
0,
);

for (int zoomLvl = region.minZoom; zoomLvl <= region.maxZoom; zoomLvl++) {
final centerTile = (region.crs.latLngToPoint(
region.originalRegion.center,
zoomLvl.toDouble(),
) /
region.options.tileSize)
.floor();
for (double zoomLvl = region.minZoom.toDouble();
zoomLvl <= region.maxZoom;
zoomLvl++) {
final scaleLvl = region.crs.scale(zoomLvl);

final (_, rawCenterY) =
region.crs.latLngToXY(region.originalRegion.center, scaleLvl);
final centerY = (rawCenterY / region.options.tileDimension).floor();

final radius = centerTile.y -
(region.crs.latLngToPoint(edgeTile, zoomLvl.toDouble()) /
region.options.tileSize)
.floor()
.y;
final (_, rawEdgeY) = region.crs.latLngToXY(edgeTile, scaleLvl);
final edgeY = (rawEdgeY / region.options.tileDimension).floor();

final radius = centerY - edgeY;
final radiusSquared = radius * radius;

if (radius == 0) {
Expand Down Expand Up @@ -113,20 +114,20 @@ class TileCounters {
final p1 = polygon.points[i1];
final p2 = polygon.points[i2];

final normal = Point(p2.y - p1.y, p1.x - p2.x);
final normal = Point(p2.$2 - p1.$2, p1.$1 - p2.$1);

var minA = largestInt;
var maxA = smallestInt;
for (final p in a.points) {
final projected = normal.x * p.x + normal.y * p.y;
final projected = normal.x * p.$1 + normal.y * p.$2;
if (projected < minA) minA = projected;
if (projected > maxA) maxA = projected;
}

var minB = largestInt;
var maxB = smallestInt;
for (final p in b.points) {
final projected = normal.x * p.x + normal.y * p.y;
final projected = normal.x * p.$1 + normal.y * p.$2;
if (projected < minB) minB = projected;
if (projected > maxB) maxB = projected;
}
Expand All @@ -145,6 +146,8 @@ class TileCounters {
for (double zoomLvl = region.minZoom.toDouble();
zoomLvl <= region.maxZoom;
zoomLvl++) {
final scaleLvl = region.crs.scale(zoomLvl);

final generatedTiles = <int>[];

for (final rect in lineOutline) {
Expand All @@ -169,51 +172,49 @@ class TileCounters {
];

final rotatedRectangleNW =
(region.crs.latLngToPoint(rotatedRectangle.topLeft, zoomLvl) /
region.options.tileSize)
(region.crs.latLngToXY(rotatedRectangle.topLeft, scaleLvl) /
region.options.tileDimension)
.floor();
final rotatedRectangleNE =
(region.crs.latLngToPoint(rotatedRectangle.topRight, zoomLvl) /
region.options.tileSize)
(region.crs.latLngToXY(rotatedRectangle.topRight, scaleLvl) /
region.options.tileDimension)
.ceil() -
const Point(1, 0);
(1, 0);
final rotatedRectangleSW =
(region.crs.latLngToPoint(rotatedRectangle.bottomLeft, zoomLvl) /
region.options.tileSize)
(region.crs.latLngToXY(rotatedRectangle.bottomLeft, scaleLvl) /
region.options.tileDimension)
.ceil() -
const Point(0, 1);
(0, 1);
final rotatedRectangleSE =
(region.crs.latLngToPoint(rotatedRectangle.bottomRight, zoomLvl) /
region.options.tileSize)
(region.crs.latLngToXY(rotatedRectangle.bottomRight, scaleLvl) /
region.options.tileDimension)
.ceil() -
const Point(1, 1);
(1, 1);

final straightRectangleNW = (region.crs.latLngToPoint(
final straightRectangleNW = (region.crs.latLngToXY(
LatLng(rotatedRectangleLats.max, rotatedRectangleLngs.min),
zoomLvl,
scaleLvl,
) /
region.options.tileSize)
region.options.tileDimension)
.floor();
final straightRectangleSE = (region.crs.latLngToPoint(
final straightRectangleSE = (region.crs.latLngToXY(
LatLng(
rotatedRectangleLats.min,
rotatedRectangleLngs.max,
),
zoomLvl,
scaleLvl,
) /
region.options.tileSize)
region.options.tileDimension)
.ceil() -
const Point(1, 1);
(1, 1);

for (int x = straightRectangleNW.x; x <= straightRectangleSE.x; x++) {
for (int x = straightRectangleNW.$1; x <= straightRectangleSE.$1; x++) {
bool foundOverlappingTile = false;
for (int y = straightRectangleNW.y; y <= straightRectangleSE.y; y++) {
final tile = _Polygon(
Point(x, y),
Point(x + 1, y),
Point(x + 1, y + 1),
Point(x, y + 1),
);
for (int y = straightRectangleNW.$2;
y <= straightRectangleSE.$2;
y++) {
final tile =
_Polygon((x, y), (x + 1, y), (x + 1, y + 1), (x, y + 1));
if (generatedTiles.contains(tile.hashCode)) continue;
if (overlap(
_Polygon(
Expand Down Expand Up @@ -251,35 +252,43 @@ class TileCounters {
for (double zoomLvl = region.minZoom.toDouble();
zoomLvl <= region.maxZoom;
zoomLvl++) {
final allOutlineTiles = <Point<int>>{};
final scaleLvl = region.crs.scale(zoomLvl);

final pointsOutline = customPolygonOutline
.map((e) => region.crs.latLngToPoint(e, zoomLvl).floor());
final allOutlineTiles = <(int, int)>{};

for (final triangle in Earcut.triangulateFromPoints(
pointsOutline.map((e) => e.toDoublePoint()),
final pointsOutline = customPolygonOutline
.map((e) => region.crs.latLngToXY(e, scaleLvl).floorToDouble());

for (final triangle in Earcut.triangulateRaw(
List.generate(
pointsOutline.length * 2,
(i) => i.isEven
? pointsOutline.elementAt(i ~/ 2).$1
: pointsOutline.elementAt(i ~/ 2).$2,
growable: false,
),
).map(pointsOutline.elementAt).slices(3)) {
final outlineTiles = {
..._bresenhamsLGA(
Point(triangle[0].x, triangle[0].y),
Point(triangle[1].x, triangle[1].y),
unscaleBy: region.options.tileSize,
triangle[0],
triangle[1],
unscaleBy: region.options.tileDimension,
),
..._bresenhamsLGA(
Point(triangle[1].x, triangle[1].y),
Point(triangle[2].x, triangle[2].y),
unscaleBy: region.options.tileSize,
triangle[1],
triangle[2],
unscaleBy: region.options.tileDimension,
),
..._bresenhamsLGA(
Point(triangle[2].x, triangle[2].y),
Point(triangle[0].x, triangle[0].y),
unscaleBy: region.options.tileSize,
triangle[2],
triangle[0],
unscaleBy: region.options.tileDimension,
),
};
allOutlineTiles.addAll(outlineTiles);

final byY = <int, Set<int>>{};
for (final Point(:x, :y) in outlineTiles) {
for (final (x, y) in outlineTiles) {
(byY[y] ??= {}).add(x);
}

Expand Down
Loading

0 comments on commit b9f94ae

Please sign in to comment.