<reponame>black-cape/vectorman<filename>vectorman/util.py
import math
from typing import Dict, Any, Tuple


def calculate_centroid(metadata: Dict[str, Any]) -> Tuple[float, float, int]:
    """Calculate a rough centroid for the metadata provided by rio-tiler.

    Args:
        metadata: the metadata generated by rio-tiler for a compliant image

    Returns:
        The centroid of the bounds polygon with the min zoom.

    """
    bounds = metadata["bounds"]["value"]
    lon = (bounds[0] + bounds[2]) / 2
    lat = (bounds[1] + bounds[3]) / 2
    return lon, lat, metadata["minzoom"]


def build_tile_url(
    image_path: str, rgb: bool = False, url_root: str = "/", is_product: bool = False
) -> str:
    """Build a Tile URL for the given image path.

    Args:
        image_path: the path to the image to be processed
        rgb (optional): if the path should be to the DEM RGB version of tiles

    Returns:
        The URL for the specified tile set.

    """
    prefix = ""
    if is_product:
        prefix = "products/"
    return (
        f"{url_root}{prefix}{'rgb' if rgb else 'tile'}/{image_path}/"
        + r"{z}/{x}/{y}.png"
    )


def snake(term: str) -> str:
    """Convert the given string to snake case.

    Args:
        term: the term/word/phrase to convert

    Returns:
        The snake-cased version of the provided identifier.

    """
    buffer = []
    for pos, character in enumerate(term):
        if character.isupper() and pos != 0:
            buffer.append("_")
        buffer.append(character.lower())
    return "".join(buffer)


def camel(term: str) -> str:
    """Convert the given string to camel case.

    Args:
        term: the term/word/phrase to convert

    Returns:
        The camel-cased version of the provided identifier.

    """
    parts = iter(term.split("_"))
    return next(parts) + "".join([chunk.title() for chunk in parts])


def coord_to_tile(lon: float, lat: float, zoom: int) -> Tuple[int, int, int]:
    """Transform the provided coordinate to a slippy-map tile.

    More information available here:
    https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Coordinates_to_tile_numbers_2

    """
    lat_rad = math.radians(lat)
    zoom_factor = 2.0 ** zoom
    xtile = int((lon + 180.0) / 360.0 * zoom_factor)
    ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * zoom_factor)
    return zoom, xtile, ytile

import math
from typing import Dict, Any, Tuple


def calculate_centroid(metadata: Dict[str, Any]) -> Tuple[float, float, int]:
    """Calculate a rough centroid for the metadata provided by rio-tiler.

    Args:
        metadata: the metadata generated by rio-tiler for a compliant image

    Returns:
        The centroid of the bounds polygon with the min zoom.

    """
    bounds = metadata["bounds"]["value"]
    lon = (bounds[0] + bounds[2]) / 2
    lat = (bounds[1] + bounds[3]) / 2
    return lon, lat, metadata["minzoom"]


def build_tile_url(
    image_path: str, rgb: bool = False, url_root: str = "/", is_product: bool = False
) -> str:
    """Build a Tile URL for the given image path.

    Args:
        image_path: the path to the image to be processed
        rgb (optional): if the path should be to the DEM RGB version of tiles

    Returns:
        The URL for the specified tile set.

    """
    prefix = ""
    if is_product:
        prefix = "products/"
    return (
        f"{url_root}{prefix}{'rgb' if rgb else 'tile'}/{image_path}/"
        + r"{z}/{x}/{y}.png"
    )


def snake(term: str) -> str:
    """Convert the given string to snake case.

    Args:
        term: the term/word/phrase to convert

    Returns:
        The snake-cased version of the provided identifier.

    """
    buffer = []
    for pos, character in enumerate(term):
        if character.isupper() and pos != 0:
            buffer.append("_")
        buffer.append(character.lower())
    return "".join(buffer)


def camel(term: str) -> str:
    """Convert the given string to camel case.

    Args:
        term: the term/word/phrase to convert

    Returns:
        The camel-cased version of the provided identifier.

    """
    parts = iter(term.split("_"))
    return next(parts) + "".join([chunk.title() for chunk in parts])


def coord_to_tile(lon: float, lat: float, zoom: int) -> Tuple[int, int, int]:
    """Transform the provided coordinate to a slippy-map tile.

    More information available here:
    https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Coordinates_to_tile_numbers_2

    """
    lat_rad = math.radians(lat)
    zoom_factor = 2.0 ** zoom
    xtile = int((lon + 180.0) / 360.0 * zoom_factor)
    ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * zoom_factor)
    return zoom, xtile, ytile
Calculate a rough centroid for the metadata provided by rio-tiler.      Args:         metadata: the metadata generated by rio-tiler for a compliant image      Returns:         The centroid of the bounds polygon with the min zoom. Build a Tile URL for the given image path.      Args:         image_path: the path to the image to be processed         rgb (optional): if the path should be to the DEM RGB version of tiles      Returns:         The URL for the specified tile set. Convert the given string to snake case.      Args:         term: the term/word/phrase to convert      Returns:         The snake-cased version of the provided identifier. Convert the given string to camel case.      Args:         term: the term/word/phrase to convert      Returns:         The camel-cased version of the provided identifier. Transform the provided coordinate to a slippy-map tile.      More information available here:     https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Coordinates_to_tile_numbers_2