utils module¶
Utility functions for anymap library.
This module contains common utility functions used across the anymap library, including functions for constructing map style URLs, handling API keys, and working with different mapping service providers.
Functions
get_env_var: Retrieve environment variables or user data keys. construct_carto_style: Construct URL for Carto style. construct_amazon_style: Construct URL for Amazon Map style. construct_maptiler_style: Construct URL for MapTiler style. maptiler_3d_style: Generate 3D terrain style configuration. construct_maplibre_style: Construct MapLibre style configuration.
Examples:
Getting an environment variable:
>>> from anymap.utils import get_env_var
>>> api_key = get_env_var("MAPTILER_KEY")
Constructing a style URL:
>>> from anymap.utils import construct_maplibre_style
>>> style = construct_maplibre_style("dark-matter")
construct_amazon_style(map_style='standard', region='us-east-1', api_key=None, token='AWS_MAPS_API_KEY')
¶
Constructs a URL for an Amazon Map style.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
map_style |
str |
The name of the MapTiler style to be accessed. It can be one of the following: standard, monochrome, satellite, hybrid. |
'standard' |
region |
str |
The region of the Amazon Map. It can be one of the following: us-east-1, us-west-2, eu-central-1, eu-west-1, ap-northeast-1, ap-northeast-2, ap-southeast-1, etc. |
'us-east-1' |
api_key |
str |
The API key for the Amazon Map. If None, the function attempts to retrieve the API key using a predefined method. |
None |
token |
str |
The token for the Amazon Map. If None, the function attempts to retrieve the API key using a predefined method. |
'AWS_MAPS_API_KEY' |
Returns:
Type | Description |
---|---|
str |
The URL for the requested Amazon Map style. |
Source code in anymap/utils.py
def construct_amazon_style(
map_style: str = "standard",
region: str = "us-east-1",
api_key: str = None,
token: str = "AWS_MAPS_API_KEY",
) -> str:
"""
Constructs a URL for an Amazon Map style.
Args:
map_style (str): The name of the MapTiler style to be accessed. It can be one of the following:
standard, monochrome, satellite, hybrid.
region (str): The region of the Amazon Map. It can be one of the following:
us-east-1, us-west-2, eu-central-1, eu-west-1, ap-northeast-1, ap-northeast-2, ap-southeast-1, etc.
api_key (str): The API key for the Amazon Map. If None, the function attempts to retrieve the API key using a predefined method.
token (str): The token for the Amazon Map. If None, the function attempts to retrieve the API key using a predefined method.
Returns:
str: The URL for the requested Amazon Map style.
"""
if map_style.lower() not in ["standard", "monochrome", "satellite", "hybrid"]:
print(
"Invalid map style. Please choose from amazon-standard, amazon-monochrome, amazon-satellite, or amazon-hybrid."
)
return None
if api_key is None:
api_key = get_env_var(token)
if api_key is None:
print("An API key is required to use the Amazon Map style.")
return None
url = f"https://maps.geo.{region}.amazonaws.com/v2/styles/{map_style.title()}/descriptor?key={api_key}"
return url
construct_carto_style(style)
¶
Constructs a URL for a Carto style with an optional API key. The URL looks like this: https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json https://basemaps.cartocdn.com/gl/positron-gl-style/style.json
Source code in anymap/utils.py
def construct_carto_style(style: str) -> str:
"""
Constructs a URL for a Carto style with an optional API key.
The URL looks like this:
https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json
https://basemaps.cartocdn.com/gl/positron-gl-style/style.json
"""
return f"https://basemaps.cartocdn.com/gl/{style.lower()}-gl-style/style.json"
construct_maplibre_style(style, **kwargs)
¶
Constructs a URL for a MapLibre style.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
style |
str |
The name of the MapLibre style to be accessed. |
required |
Source code in anymap/utils.py
def construct_maplibre_style(style: str, **kwargs) -> str:
"""
Constructs a URL for a MapLibre style.
Args:
style (str): The name of the MapLibre style to be accessed.
"""
carto_basemaps = [
"dark-matter",
"positron",
"voyager",
"positron-nolabels",
"dark-matter-nolabels",
"voyager-nolabels",
]
openfreemap_basemaps = [
"liberty",
"bright",
"positron2",
]
if isinstance(style, str):
if style.startswith("https"):
response = requests.get(style, timeout=10)
if response.status_code != 200:
print(
"The provided style URL is invalid. Falling back to 'dark-matter'."
)
style = "dark-matter"
else:
style = json.loads(response.text)
elif style.startswith("3d-"):
style = maptiler_3d_style(
style=style.replace("3d-", "").lower(),
exaggeration=kwargs.pop("exaggeration", 1),
tile_size=kwargs.pop("tile_size", 512),
hillshade=kwargs.pop("hillshade", True),
)
elif style.startswith("amazon-"):
style = construct_amazon_style(
map_style=style.replace("amazon-", "").lower(),
region=kwargs.pop("region", "us-east-1"),
api_key=kwargs.pop("api_key", None),
token=kwargs.pop("token", "AWS_MAPS_API_KEY"),
)
elif style.lower() in carto_basemaps:
style = construct_carto_style(style.lower())
elif style.lower() in openfreemap_basemaps:
if style == "positron2":
style = "positron"
style = f"https://tiles.openfreemap.org/styles/{style.lower()}"
elif style == "demotiles":
style = "https://demotiles.maplibre.org/style.json"
else:
style = construct_maptiler_style(style)
if style in carto_basemaps:
style = construct_carto_style(style)
return style
construct_maptiler_style(style, api_key=None)
¶
Constructs a URL for a MapTiler style with an optional API key.
This function generates a URL for accessing a specific MapTiler map style. If an API key is not provided, it attempts to retrieve one using a predefined method. If the request to MapTiler fails, it defaults to a "liberty" style.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
style |
str |
The name of the MapTiler style to be accessed. It can be one of the following: aquarelle, backdrop, basic, bright, dataviz, landscape, ocean, openstreetmap, outdoor, satellite, streets, toner, topo, winter, etc. |
required |
api_key |
Optional[str] |
An optional API key for accessing MapTiler services. If None, the function attempts to retrieve the API key using a predefined method. Defaults to None. |
None |
Returns:
Type | Description |
---|---|
str |
The URL for the requested MapTiler style. If the request fails, returns a URL for the "liberty" style. |
Exceptions:
Type | Description |
---|---|
requests.exceptions.RequestException |
If the request to the MapTiler API fails. |
Source code in anymap/utils.py
def construct_maptiler_style(style: str, api_key: Optional[str] = None) -> str:
"""
Constructs a URL for a MapTiler style with an optional API key.
This function generates a URL for accessing a specific MapTiler map style. If an API key is not provided,
it attempts to retrieve one using a predefined method. If the request to MapTiler fails, it defaults to
a "liberty" style.
Args:
style (str): The name of the MapTiler style to be accessed. It can be one of the following:
aquarelle, backdrop, basic, bright, dataviz, landscape, ocean, openstreetmap, outdoor,
satellite, streets, toner, topo, winter, etc.
api_key (Optional[str]): An optional API key for accessing MapTiler services. If None, the function
attempts to retrieve the API key using a predefined method. Defaults to None.
Returns:
str: The URL for the requested MapTiler style. If the request fails, returns a URL for the "liberty" style.
Raises:
requests.exceptions.RequestException: If the request to the MapTiler API fails.
"""
if api_key is None:
api_key = get_env_var("MAPTILER_KEY")
url = f"https://api.maptiler.com/maps/{style}/style.json?key={api_key}"
response = requests.get(url, timeout=10)
if response.status_code != 200:
# print(
# "Failed to retrieve the MapTiler style. Defaulting to OpenFreeMap 'liberty' style."
# )
url = "https://tiles.openfreemap.org/styles/liberty"
return url
get_env_var(name=None, key=None)
¶
Retrieves an environment variable. If a key is provided, it is returned directly. If a name is provided, the function attempts to retrieve the key from user data (if running in Google Colab) or from environment variables.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
Optional[str] |
The name of the key to retrieve. Defaults to None. |
None |
key |
Optional[str] |
The key to return directly. Defaults to None. |
None |
Returns:
Type | Description |
---|---|
Optional[str] |
The retrieved key, or None if no key was found. |
Source code in anymap/utils.py
def get_env_var(name: Optional[str] = None, key: Optional[str] = None) -> Optional[str]:
"""
Retrieves an environment variable. If a key is provided, it is returned directly. If a
name is provided, the function attempts to retrieve the key from user data
(if running in Google Colab) or from environment variables.
Args:
name (Optional[str], optional): The name of the key to retrieve. Defaults to None.
key (Optional[str], optional): The key to return directly. Defaults to None.
Returns:
Optional[str]: The retrieved key, or None if no key was found.
"""
if key is not None:
return key
if name is not None:
try:
if _in_colab_shell():
from google.colab import userdata # pylint: disable=E0611
return userdata.get(name)
except Exception:
pass
return os.environ.get(name)
return None
maptiler_3d_style(style='satellite', exaggeration=1, tile_size=512, tile_type=None, max_zoom=24, hillshade=True, token='MAPTILER_KEY', api_key=None)
¶
Get the 3D terrain style for the map.
This function generates a style dictionary for the map that includes 3D terrain features. The terrain exaggeration and API key can be specified. If the API key is not provided, it will be retrieved using the specified token.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
style |
str |
The name of the MapTiler style to be accessed. It can be one of the following: aquarelle, backdrop, basic, bright, dataviz, hillshade, landscape, ocean, openstreetmap, outdoor, satellite, streets, toner, topo, winter, etc. |
'satellite' |
exaggeration |
float |
The terrain exaggeration. Defaults to 1. |
1 |
tile_size |
int |
The size of the tiles. Defaults to 512. |
512 |
tile_type |
str |
The type of the tiles. It can be one of the following: webp, png, jpg. Defaults to None. |
None |
max_zoom |
int |
The maximum zoom level. Defaults to 24. |
24 |
hillshade |
bool |
Whether to include hillshade. Defaults to True. |
True |
token |
str |
The token to use to retrieve the API key. Defaults to "MAPTILER_KEY". |
'MAPTILER_KEY' |
api_key |
Optional[str] |
The API key. If not provided, it will be retrieved using the token. |
None |
Returns:
Type | Description |
---|---|
Dict[str, Any] |
The style dictionary for the map. |
Exceptions:
Type | Description |
---|---|
ValueError |
If the API key is not provided and cannot be retrieved using the token. |
Source code in anymap/utils.py
def maptiler_3d_style(
style="satellite",
exaggeration: float = 1,
tile_size: int = 512,
tile_type: str = None,
max_zoom: int = 24,
hillshade: bool = True,
token: str = "MAPTILER_KEY",
api_key: Optional[str] = None,
) -> Dict[str, Any]:
"""
Get the 3D terrain style for the map.
This function generates a style dictionary for the map that includes 3D terrain features.
The terrain exaggeration and API key can be specified. If the API key is not provided,
it will be retrieved using the specified token.
Args:
style (str): The name of the MapTiler style to be accessed. It can be one of the following:
aquarelle, backdrop, basic, bright, dataviz, hillshade, landscape, ocean, openstreetmap, outdoor,
satellite, streets, toner, topo, winter, etc.
exaggeration (float, optional): The terrain exaggeration. Defaults to 1.
tile_size (int, optional): The size of the tiles. Defaults to 512.
tile_type (str, optional): The type of the tiles. It can be one of the following:
webp, png, jpg. Defaults to None.
max_zoom (int, optional): The maximum zoom level. Defaults to 24.
hillshade (bool, optional): Whether to include hillshade. Defaults to True.
token (str, optional): The token to use to retrieve the API key. Defaults to "MAPTILER_KEY".
api_key (Optional[str], optional): The API key. If not provided, it will be retrieved using the token.
Returns:
Dict[str, Any]: The style dictionary for the map.
Raises:
ValueError: If the API key is not provided and cannot be retrieved using the token.
"""
if api_key is None:
api_key = get_env_var(token)
if api_key is None:
print("An API key is required to use the 3D terrain feature.")
return "dark-matter"
if style == "terrain":
style = "satellite"
elif style == "hillshade":
style = None
if tile_type is None:
image_types = {
"aquarelle": "webp",
"backdrop": "png",
"basic": "png",
"basic-v2": "png",
"bright": "png",
"bright-v2": "png",
"dataviz": "png",
"hybrid": "jpg",
"landscape": "png",
"ocean": "png",
"openstreetmap": "jpg",
"outdoor": "png",
"outdoor-v2": "png",
"satellite": "jpg",
"toner": "png",
"toner-v2": "png",
"topo": "png",
"topo-v2": "png",
"winter": "png",
"winter-v2": "png",
}
if style in image_types:
tile_type = image_types[style]
else:
tile_type = "png"
layers = []
if isinstance(style, str):
layers.append({"id": style, "type": "raster", "source": style})
if hillshade:
layers.append(
{
"id": "hillshade",
"type": "hillshade",
"source": "hillshadeSource",
"layout": {"visibility": "visible"},
"paint": {"hillshade-shadow-color": "#473B24"},
}
)
if style == "ocean":
sources = {
"terrainSource": {
"type": "raster-dem",
"url": f"https://api.maptiler.com/tiles/ocean-rgb/tiles.json?key={api_key}",
"tileSize": tile_size,
},
"hillshadeSource": {
"type": "raster-dem",
"url": f"https://api.maptiler.com/tiles/ocean-rgb/tiles.json?key={api_key}",
"tileSize": tile_size,
},
}
else:
sources = {
"terrainSource": {
"type": "raster-dem",
"url": f"https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key={api_key}",
"tileSize": tile_size,
},
"hillshadeSource": {
"type": "raster-dem",
"url": f"https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key={api_key}",
"tileSize": tile_size,
},
}
if isinstance(style, str):
sources[style] = {
"type": "raster",
"tiles": [
"https://api.maptiler.com/maps/"
+ style
+ "/{z}/{x}/{y}."
+ tile_type
+ "?key="
+ api_key
],
"tileSize": tile_size,
"attribution": "© MapTiler",
"maxzoom": max_zoom,
}
style = {
"version": 8,
"sources": sources,
"layers": layers,
"terrain": {"source": "terrainSource", "exaggeration": exaggeration},
}
return style