Skip to content

Conversation

@jonhnet
Copy link
Contributor

@jonhnet jonhnet commented Oct 6, 2025

Fixes missing tiles at zoom levels 8 and above, part of issue #365

The bug: At zoom 7 and below, all tiles are included in region zip files regardless of geography (line 161). At zoom 8+, tiles are filtered by checking if they fall within region boundaries. However, the original is_in() function only checked if a single point (the tile's upper-left corner) was inside the region boundary. This incorrectly excluded tiles that overlapped the region boundary but whose upper-left corner was outside. That caused a column of missing tiles -- less frustrating as you zoom in, but at zoom level 8, 1.4 degrees of longitude are missing. For example, you can't find KONP on the sectional chart at zoom 8; it's in column 39, which is absent from the zip file.

To fix this, I replaced is_in with Area.overlaps. I replaced the chain of singleton arguments with an Area datatype to make the code and the overlaps condition more readable, and use that type to represent both the constant region definitions and the tile bounds.

I tested this logic change locally with a one-off unit test that reproduced the old and new logic. I didn't include a unit test because the present code doesn't provide good boundaries for that. I have not tested it end-to-end on a real sectional chart.

…rner point of each tile.

Fixes missing tiles at zoom levels 8 and above.

The bug: At zoom 7 and below, all tiles are included in region zip files
regardless of geography (line 161). At zoom 8+, tiles are filtered by
checking if they fall within region boundaries. However, the original is_in()
function only checked if a single point (the tile's upper-left corner) was
inside the region boundary. This incorrectly excluded tiles that overlapped
the region boundary but whose upper-left corner was outside. That caused a
column of missing tiles -- less frustrating as you zoom in, but at zoom level
8, 1.4 degrees of longitude are missing. For example, you can't find
KONP on the sectional chart at zoom 8; it's in column 39, which is absent
from the zip file.

To fix this, I replaced is_in with Area.overlaps. I replaced the chain of
singleton arguments with an Area datatype to make the code and the overlaps
condition more readable, and use that type to represent both the constant
region definitions and the tile bounds.
@jonhnet
Copy link
Contributor Author

jonhnet commented Oct 6, 2025

fixes part of apps4av/avare#365

@jonhnet
Copy link
Contributor Author

jonhnet commented Oct 7, 2025

I ran sec.py, and it correctly generates the missing column of tiles at zoom level 8 & 9. Hooray!

Copy link
Owner

@apps4av apps4av left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. But how big of a problem is it ?
The chart code previously written was getting so complicated that it was unreliable and we were missing release dates. Hence the chart code was rewritten to make it as simple as possible and resist feature creeps. Since there are no complaints on the forum regarding this, we will need to wait to merge it.

@jonhnet
Copy link
Contributor Author

jonhnet commented Oct 7, 2025

Notably, this is not a feature creep, it's a bug fix: there are tiles missing. Try putting your airplane on KONP (Oregon coast, near the boundary of the NW region) and zooming in and out. Far enough out (zoom level 7 or below), it works fine. But at zoom level 8, the coastal part of oregon is just missing, a black hole. "NW goes to the Pacific" isn't a feature, it's a requirement that the app currently doesn't satisfy.

The complaint is issue #365 over on the app repository. It has been around for a long time.

@jonhnet
Copy link
Contributor Author

jonhnet commented Oct 7, 2025

The bug boils down to: the existing code tests whether a tile's northwest corner falls inside the region boundary. Instead, it should test whether any of the tile's area overlaps the region boundary.

Maybe one thing that is off-putting is the introduction of the Area type. I could express the fix in fewer lines of code with a long chain of inequalities inlined at the site of the comparison. I preferred to introduce the Area type because it makes a clean separation. At the call site, we express the critical idea that fixes the bug: "does the area of this tile overlap with the area of the region?" Then all the clumsy inequality logic is bundled together inside the Area.overlaps method.

@apps4av
Copy link
Owner

apps4av commented Oct 7, 2025 via email

@jonhnet
Copy link
Contributor Author

jonhnet commented Oct 7, 2025

There is no region west of NW. (Well, AK and PAC are west of NW, but too far west and not at the same latitude.)

I went looking to see if this bug affects the northern border of NW, but it doesn't because the region border is 50°N and the sectional ends at 49°N. A workaround would be to move the western boundary of every region at lest 1.41° more west. I'm not sure that's a robust workaround; just that the SEC tiles happened to be 1.41° wide at zoom 8.

But also ... why wouldn't we want to fix a bug that omits tiles that belong in a given region? It seems much easier to understand than hiding the bug by changing region boundaries.

(By the way, I freaking love the regions. Chart list maintenance was such a nightmare in the prior model, but now I just select a few regions and I'm off to the airport. Thanks!)

@apps4av
Copy link
Owner

apps4av commented Oct 8, 2025 via email

…west corner.

At zoom 8+, tiles were filtered by checking if the northwest corner
was inside the region boundary. This incorrectly excluded tiles that
overlapped the region but whose northwest corner was outside.
@jonhnet jonhnet closed this Oct 8, 2025
@jonhnet jonhnet reopened this Oct 8, 2025
@apps4av
Copy link
Owner

apps4av commented Oct 8, 2025

will be merged on next cycle.

@apps4av apps4av merged commit d532140 into apps4av:master Oct 19, 2025
@jonhnet jonhnet deleted the fix-tile-overlap-filtering branch October 20, 2025 03:06
@apps4av
Copy link
Owner

apps4av commented Nov 29, 2025

@apps4av
Copy link
Owner

apps4av commented Nov 29, 2025

@jonhnet

@jonhnet
Copy link
Contributor Author

jonhnet commented Nov 29, 2025

I'll take a look

@jonhnet
Copy link
Contributor Author

jonhnet commented Nov 30, 2025

Gah! My apologies. The call to projection.findBounds on common.py:122 assigns the second result to lat_max and the fourth to lat_min, based on variables named latU and latL in projection.py:93. As it turns out, latU is the lesser value (south-ier), so the comparison logic was reading the tile upside down.

I have made the following changes:

  • Added an assertion that we're interpreting the results of findBounds correctly. I confirmed that it fires before the actual fix is applied.
  • Swapped the order of the let assignments to fix the bug.
  • Renamed latU and latL in findBounds to eliminate this trap for future readers. (The return parameter order of findBounds is now funky, but I didn't want to risk disturbing that.)
  • Ran a test harness locally:

The harness runs the original code (before this PR, which lost west coast airports), the broken d532140 version (which lost the top row of tiles due to this bug), and the proposed fix. That harness compares the entire list of tiles generated for sectionals, and confirms that (a) original code is missing left tiles and d532140 indeed misses the top row, so the harness is working, and (b) the proposed fix produces a superset of the original and d532140. That should give us confidence that another bug isn't lurking in this fix.

  • I also ran sec.py to confirm that

Based on the harness results, you should be able to re-run the tile generation and get new zip files that have the missing files (and no less than we had before). I don't know how you mark downloads to be re-enabled inside a cycle, but I hope it's feasible.

My apologies for missing this bug -- I should have tried that test harness experiment the first time to detect any loss of tiles.

@jonhnet
Copy link
Contributor Author

jonhnet commented Nov 30, 2025

Proposed fix in #24 .

@b-spatz
Copy link

b-spatz commented Dec 19, 2025

you should be able to re-run the tile generation [...]
I don't know how you mark downloads to be re-enabled inside a cycle, but I hope it's feasible.

I was expecting that 2512 be re-run and overwrite the defective data. That would have avoided any issues for folks who had not yet updated their data. Otherwise, you would just mark your region for update (or worse case delete, then download again).

But what happened was the fixed data was issued as 2513 which required everyone to (re-)download from an unexpected future cycle which caused confusion and questions on the forum.

I would like to understand why 2513 made more sense than just reissue 2512. I assume I misunderstand something.
Thanks in advance.

@apps4av
Copy link
Owner

apps4av commented Dec 19, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants