Skip to content

Commit

Permalink
docs: update docstring for tile_index.py (#473)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulfouquet authored May 11, 2023
1 parent 3dbb5d8 commit 38ef275
Showing 1 changed file with 49 additions and 20 deletions.
69 changes: 49 additions & 20 deletions scripts/tile/tile_index.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
from typing import NamedTuple, Union

SHEET_WIDTH = 24_000 # The width of a 1:50k sheet in metres
SHEET_HEIGHT = 36_000 # The height of a 1:50k sheet in metres
SHEET_ORIGIN_LEFT = 988_000 # The NZTM x coordinate of the left edge of 1:50k sheet which would be at column position 00
SHEET_ORIGIN_TOP = 6_234_000 # The NZTM y coordinate of the top edge of sheets in row AS (the northernmost row)
SHEET_MIN_X = SHEET_ORIGIN_LEFT + (4 * SHEET_WIDTH) # The minimum x coordinate of a valid sheet / tile
SHEET_MAX_X = SHEET_ORIGIN_LEFT + (46 * SHEET_WIDTH) # The maximum x coordinate of a valid sheet / tile
SHEET_MIN_Y = SHEET_ORIGIN_TOP - (41 * SHEET_HEIGHT) # The minimum y coordinate of a valid sheet / tile
SHEET_MAX_Y = SHEET_ORIGIN_TOP # The maximum y coordinate of a valid sheet / tile
# Ranges of valid sheet columns for each sheet row. Keys are the row names, and values are ranges
# between which there are valid rows. For example `"AS": [(21, 22), (24, 24)]` means the valid
# sheets in row AS are AS21, AS22, and AS24.
SHEET_WIDTH = 24_000
""" Width of Topo 1:50k mapsheets (meters) """
SHEET_HEIGHT = 36_000
""" Height of Topo 1:50k mapsheets (meters) """
SHEET_ORIGIN_LEFT = 988_000
""" The NZTM x coordinate of the left edge of 1:50k mapsheets which would be at column position 00 """
SHEET_ORIGIN_TOP = 6_234_000
""" The NZTM y coordinate of the top edge of 1:50k mapsheets in row AS (the northernmost row) """
SHEET_MIN_X = SHEET_ORIGIN_LEFT + (4 * SHEET_WIDTH)
""" The minimum x coordinate of a valid sheet / tile """
SHEET_MAX_X = SHEET_ORIGIN_LEFT + (46 * SHEET_WIDTH)
""" The maximum x coordinate of a valid sheet / tile """
SHEET_MIN_Y = SHEET_ORIGIN_TOP - (41 * SHEET_HEIGHT)
""" The minimum y coordinate of a valid sheet / tile """
SHEET_MAX_Y = SHEET_ORIGIN_TOP
""" The maximum y coordinate of a valid sheet / tile """
SHEET_RANGES = {
"AS": [(21, 22), (24, 24)],
"AT": [(23, 26)],
Expand Down Expand Up @@ -55,10 +60,19 @@
"CJ": [(7, 11)],
"CK": [(7, 9)],
}
""" Ranges of valid sheet columns for each sheet row.
Keys are the row names, and values are ranges between which there are valid rows.
For example `"AS": [(21, 22), (24, 24)]` means the valid sheets in row AS are AS21, AS22, and AS24.
See `sheet index diagram` at
https://www.linz.govt.nz/products-services/maps/new-zealand-topographic-maps/topo50-map-chooser/topo50-sheet-index """


GRID_SIZES = [10_000, 5_000, 2_000, 1_000, 500]
""" Allowed grid sized, these should exist in the LINZ Data service (meters) """
GRID_SIZE_MAX = 50_000
# Correction is set to 1 centimeter
""" Base scale Topo 1:50k mapsheets (meters) """
ROUND_CORRECTION = 0.01
""" Correction set to `1` centimer """


class TileIndexException(Exception):
Expand All @@ -75,24 +89,35 @@ class Point(NamedTuple):
def round_with_correction(value: Union[int, float]) -> int | float:
"""Round a value to the next or previous unit ROUND_CORRECTION.
Python round() can be 'inaccurate', note that:
round(0.015) == 0.01
round(0.985) == 0.99
>>> round(0.015)
0.01
>>> round(0.985)
0.99
Args:
value (Union[int, float]): the value to round with correction.
value: the value to round with correction.
Returns:
int | float: the rounded and (maybe) corrected value.
the rounded and (maybe) corrected value.
Examples:
>>> round_with_correction(1643679.969)
1643679.97
>>> round_with_correction(5444160.015)
5444160
"""
if isinstance(value, int):
return value

# Round to centimeter precision
correction = rounded_value = round(value, 2)

# The rounded value is not an integer
if not rounded_value.is_integer():
# Try to get an integer by adding the `ROUND_CORRECTION`
if (rounded_value + ROUND_CORRECTION).is_integer():
correction = rounded_value + ROUND_CORRECTION
# Try to get an integer by substracting the `ROUND_CORRECTION`
elif (rounded_value - ROUND_CORRECTION).is_integer():
correction = rounded_value - ROUND_CORRECTION

Expand All @@ -106,14 +131,18 @@ def get_tile_name(origin: Point, grid_size: int) -> str:
"""Get the tile name from an origin point and the grid size (or scale).
Args:
origin (Point): The origin point of the tile to get the name for.
grid_size (int): The size of the grid (or scale).
origin: The origin point of the tile to get the name for.
grid_size: The size of the grid (or scale).
Raises:
TileIndexException: If the input data don't allow to get the tile.
Returns:
str: The generated tile name ('sheetCode_gridSize_tileId').
Example:
>>> get_tile_name(Point(1236640, 4837560), 500)
"CG10_500_080037.tiff"
"""
# pylint: disable-msg=too-many-locals
if not grid_size in GRID_SIZES:
Expand All @@ -122,7 +151,7 @@ def get_tile_name(origin: Point, grid_size: int) -> str:
origin_x = round_with_correction(origin[0])
origin_y = round_with_correction(origin[1])

# If x or y is not a round number, the origin is not valid
# If x or y is not a round number after being corrected, the origin is not valid
if not isinstance(origin_x, int) or not isinstance(origin_y, int):
raise TileIndexException(f"The origin is invalid x = {origin_x}, y = {origin_y}")

Expand All @@ -131,7 +160,7 @@ def get_tile_name(origin: Point, grid_size: int) -> str:
tile_height = SHEET_HEIGHT // scale
nb_digits = 2
if grid_size == 500:
nb_digits = 3
nb_digits = 3 # 1:500 X/Y is 3 digits not 2

if not SHEET_MIN_X <= origin_x <= SHEET_MAX_X:
raise TileIndexException(f"x must be between {SHEET_MIN_X} and {SHEET_MAX_X}, was {origin_x}")
Expand Down

0 comments on commit 38ef275

Please sign in to comment.