@@ -38,15 +38,17 @@ class TileCounters {
3838 for (double zoomLvl = region.minZoom.toDouble ();
3939 zoomLvl <= region.maxZoom;
4040 zoomLvl++ ) {
41- final nwPoint = (region.crs.latLngToPoint (northWest, zoomLvl) /
42- region.options.tileSize)
43- .floor ();
44- final sePoint = (region.crs.latLngToPoint (southEast, zoomLvl) /
45- region.options.tileSize)
46- .ceil () -
47- const Point (1 , 1 );
48-
49- tileCount += (sePoint.x - nwPoint.x + 1 ) * (sePoint.y - nwPoint.y + 1 );
41+ final scaleLvl = region.crs.scale (zoomLvl);
42+
43+ final nw = region.crs.latLngToXY (northWest, scaleLvl);
44+ final nwX = (nw.$1 / region.options.tileDimension).floor ();
45+ final nwY = (nw.$2 / region.options.tileDimension).floor ();
46+
47+ final se = region.crs.latLngToXY (southEast, scaleLvl);
48+ final seX = (se.$1 / region.options.tileDimension).ceil () - 1 ;
49+ final seY = (se.$2 / region.options.tileDimension).ceil () - 1 ;
50+
51+ tileCount += (seX - nwX + 1 ) * (seY - nwY + 1 );
5052 }
5153
5254 return _trimToRange (region, tileCount);
@@ -64,20 +66,19 @@ class TileCounters {
6466 0 ,
6567 );
6668
67- for (int zoomLvl = region.minZoom; zoomLvl <= region.maxZoom; zoomLvl++ ) {
68- final centerTile = (region.crs.latLngToPoint (
69- region.originalRegion.center,
70- zoomLvl.toDouble (),
71- ) /
72- region.options.tileSize)
73- .floor ();
69+ for (double zoomLvl = region.minZoom.toDouble ();
70+ zoomLvl <= region.maxZoom;
71+ zoomLvl++ ) {
72+ final scaleLvl = region.crs.scale (zoomLvl);
73+
74+ final (_, rawCenterY) =
75+ region.crs.latLngToXY (region.originalRegion.center, scaleLvl);
76+ final centerY = (rawCenterY / region.options.tileDimension).floor ();
7477
75- final radius = centerTile.y -
76- (region.crs.latLngToPoint (edgeTile, zoomLvl.toDouble ()) /
77- region.options.tileSize)
78- .floor ()
79- .y;
78+ final (_, rawEdgeY) = region.crs.latLngToXY (edgeTile, scaleLvl);
79+ final edgeY = (rawEdgeY / region.options.tileDimension).floor ();
8080
81+ final radius = centerY - edgeY;
8182 final radiusSquared = radius * radius;
8283
8384 if (radius == 0 ) {
@@ -113,20 +114,20 @@ class TileCounters {
113114 final p1 = polygon.points[i1];
114115 final p2 = polygon.points[i2];
115116
116- final normal = Point (p2.y - p1.y , p1.x - p2.x );
117+ final normal = Point (p2.$2 - p1.$2 , p1.$1 - p2.$1 );
117118
118119 var minA = largestInt;
119120 var maxA = smallestInt;
120121 for (final p in a.points) {
121- final projected = normal.x * p.x + normal.y * p.y ;
122+ final projected = normal.x * p.$1 + normal.y * p.$2 ;
122123 if (projected < minA) minA = projected;
123124 if (projected > maxA) maxA = projected;
124125 }
125126
126127 var minB = largestInt;
127128 var maxB = smallestInt;
128129 for (final p in b.points) {
129- final projected = normal.x * p.x + normal.y * p.y ;
130+ final projected = normal.x * p.$1 + normal.y * p.$2 ;
130131 if (projected < minB) minB = projected;
131132 if (projected > maxB) maxB = projected;
132133 }
@@ -145,6 +146,8 @@ class TileCounters {
145146 for (double zoomLvl = region.minZoom.toDouble ();
146147 zoomLvl <= region.maxZoom;
147148 zoomLvl++ ) {
149+ final scaleLvl = region.crs.scale (zoomLvl);
150+
148151 final generatedTiles = < int > [];
149152
150153 for (final rect in lineOutline) {
@@ -169,51 +172,49 @@ class TileCounters {
169172 ];
170173
171174 final rotatedRectangleNW =
172- (region.crs.latLngToPoint (rotatedRectangle.topLeft, zoomLvl ) /
173- region.options.tileSize )
175+ (region.crs.latLngToXY (rotatedRectangle.topLeft, scaleLvl ) /
176+ region.options.tileDimension )
174177 .floor ();
175178 final rotatedRectangleNE =
176- (region.crs.latLngToPoint (rotatedRectangle.topRight, zoomLvl ) /
177- region.options.tileSize )
179+ (region.crs.latLngToXY (rotatedRectangle.topRight, scaleLvl ) /
180+ region.options.tileDimension )
178181 .ceil () -
179- const Point (1 , 0 );
182+ (1 , 0 );
180183 final rotatedRectangleSW =
181- (region.crs.latLngToPoint (rotatedRectangle.bottomLeft, zoomLvl ) /
182- region.options.tileSize )
184+ (region.crs.latLngToXY (rotatedRectangle.bottomLeft, scaleLvl ) /
185+ region.options.tileDimension )
183186 .ceil () -
184- const Point (0 , 1 );
187+ (0 , 1 );
185188 final rotatedRectangleSE =
186- (region.crs.latLngToPoint (rotatedRectangle.bottomRight, zoomLvl ) /
187- region.options.tileSize )
189+ (region.crs.latLngToXY (rotatedRectangle.bottomRight, scaleLvl ) /
190+ region.options.tileDimension )
188191 .ceil () -
189- const Point (1 , 1 );
192+ (1 , 1 );
190193
191- final straightRectangleNW = (region.crs.latLngToPoint (
194+ final straightRectangleNW = (region.crs.latLngToXY (
192195 LatLng (rotatedRectangleLats.max, rotatedRectangleLngs.min),
193- zoomLvl ,
196+ scaleLvl ,
194197 ) /
195- region.options.tileSize )
198+ region.options.tileDimension )
196199 .floor ();
197- final straightRectangleSE = (region.crs.latLngToPoint (
200+ final straightRectangleSE = (region.crs.latLngToXY (
198201 LatLng (
199202 rotatedRectangleLats.min,
200203 rotatedRectangleLngs.max,
201204 ),
202- zoomLvl ,
205+ scaleLvl ,
203206 ) /
204- region.options.tileSize )
207+ region.options.tileDimension )
205208 .ceil () -
206- const Point (1 , 1 );
209+ (1 , 1 );
207210
208- for (int x = straightRectangleNW.x ; x <= straightRectangleSE.x ; x++ ) {
211+ for (int x = straightRectangleNW.$1 ; x <= straightRectangleSE.$1 ; x++ ) {
209212 bool foundOverlappingTile = false ;
210- for (int y = straightRectangleNW.y; y <= straightRectangleSE.y; y++ ) {
211- final tile = _Polygon (
212- Point (x, y),
213- Point (x + 1 , y),
214- Point (x + 1 , y + 1 ),
215- Point (x, y + 1 ),
216- );
213+ for (int y = straightRectangleNW.$2;
214+ y <= straightRectangleSE.$2;
215+ y++ ) {
216+ final tile =
217+ _Polygon ((x, y), (x + 1 , y), (x + 1 , y + 1 ), (x, y + 1 ));
217218 if (generatedTiles.contains (tile.hashCode)) continue ;
218219 if (overlap (
219220 _Polygon (
@@ -251,35 +252,43 @@ class TileCounters {
251252 for (double zoomLvl = region.minZoom.toDouble ();
252253 zoomLvl <= region.maxZoom;
253254 zoomLvl++ ) {
254- final allOutlineTiles = < Point < int > > {} ;
255+ final scaleLvl = region.crs. scale (zoomLvl) ;
255256
256- final pointsOutline = customPolygonOutline
257- .map ((e) => region.crs.latLngToPoint (e, zoomLvl).floor ());
257+ final allOutlineTiles = < (int , int )> {};
258258
259- for (final triangle in Earcut .triangulateFromPoints (
260- pointsOutline.map ((e) => e.toDoublePoint ()),
259+ final pointsOutline = customPolygonOutline
260+ .map ((e) => region.crs.latLngToXY (e, scaleLvl).floorToDouble ());
261+
262+ for (final triangle in Earcut .triangulateRaw (
263+ List .generate (
264+ pointsOutline.length * 2 ,
265+ (i) => i.isEven
266+ ? pointsOutline.elementAt (i ~ / 2 ).$1
267+ : pointsOutline.elementAt (i ~ / 2 ).$2,
268+ growable: false ,
269+ ),
261270 ).map (pointsOutline.elementAt).slices (3 )) {
262271 final outlineTiles = {
263272 ..._bresenhamsLGA (
264- Point ( triangle[0 ].x, triangle[ 0 ].y) ,
265- Point ( triangle[1 ].x, triangle[ 1 ].y) ,
266- unscaleBy: region.options.tileSize ,
273+ triangle[0 ],
274+ triangle[1 ],
275+ unscaleBy: region.options.tileDimension ,
267276 ),
268277 ..._bresenhamsLGA (
269- Point ( triangle[1 ].x, triangle[ 1 ].y) ,
270- Point ( triangle[2 ].x, triangle[ 2 ].y) ,
271- unscaleBy: region.options.tileSize ,
278+ triangle[1 ],
279+ triangle[2 ],
280+ unscaleBy: region.options.tileDimension ,
272281 ),
273282 ..._bresenhamsLGA (
274- Point ( triangle[2 ].x, triangle[ 2 ].y) ,
275- Point ( triangle[0 ].x, triangle[ 0 ].y) ,
276- unscaleBy: region.options.tileSize ,
283+ triangle[2 ],
284+ triangle[0 ],
285+ unscaleBy: region.options.tileDimension ,
277286 ),
278287 };
279288 allOutlineTiles.addAll (outlineTiles);
280289
281290 final byY = < int , Set <int >> {};
282- for (final Point ( : x, : y) in outlineTiles) {
291+ for (final ( x, y) in outlineTiles) {
283292 (byY[y] ?? = {}).add (x);
284293 }
285294
0 commit comments