mapbox / mapbox/mercantile

Don't allow creating tiles with negative zoom levels.

Open
#141 0 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
453
Forks
70
PR merge metrics
No merged PRs in 30d

Description

This was first brought up in https://github.com/mapbox/mercantile/issues/122#issuecomment-788116884 which mentions the use case of calculating the parent of a zoom 0 tile:
```python
>>> mercantile.parent(mercantile.Tile(0,0,0))
Tile(x=0, y=0, z=-1)
```

The zoom 0 parent tile case was fixed in https://github.com/mapbox/mercantile/pull/130, the changelog entry from that PR says:
> The Tile constructor in mercantile 2.0 will refuse to make tiles with X and Y
indexes outside of the range 0 <= value <= 2 ** zoom. It will also require
indexes to be integers.

But this constraint actually isn't true, here is a really easy way to break it:
```python
import mercantile

zoom = -1
min_index = 0
max_index = 2 ** zoom

tile = mercantile.Tile(x=10, y=10, z=zoom)
assert min_index <= tile.x <= max_index # raises AssertionError
assert min_index <= tile.y <= max_index # raises AssertionError
```

The easiest way to make the aforementioned constraint actually work is to prevent users from creating tiles with a negative zoom level, and in my opinion this is really what the constraint is trying to do. Mercantile is a library for `Spherical mercator coordinate and tile utilities`. By definition the lowest zoom level in the mercator grid is zoom 0, at which point a single tile covers the the entire world. So even allowing users to provide a negative zoom seems to break the original intention of the library, and can lead to some very unintuitive behavior that doesn't align with how the mercator grid works in reality:

```python
tile = mercantile.Tile(x=0, y=0, z=-1)
children = mercantile.children(tile)

# Mercator grid by definition only has a single Z0 tile
assert len(children) == 4
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Tile constructor and the parent/children behavior described in the issue. Add coverage for rejecting a negative zoom level and verify that zoom 0 remains the lowest valid level, including the reported parent and children cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.