|
1 | 1 | """Parameters for functions plotting maps using ipyleaflet.""" |
2 | 2 |
|
| 3 | +import warnings |
3 | 4 | from typing import Dict, Tuple, Union |
4 | 5 |
|
5 | 6 | import ipyleaflet # type: ignore |
|
17 | 18 |
|
18 | 19 | zoom_default: zoom = 3 |
19 | 20 |
|
20 | | -basemap_abbrevs = { |
21 | | - "mapnik": ipyleaflet.basemaps.OpenStreetMap.Mapnik, |
22 | | - "natgeoworldmap": ipyleaflet.basemaps.Esri.NatGeoWorldMap, |
23 | | - "opentopomap": ipyleaflet.basemaps.OpenTopoMap, |
24 | | - "positron": ipyleaflet.basemaps.CartoDB.Positron, |
25 | | - "satellite": ipyleaflet.basemaps.Gaode.Satellite, |
26 | | - "worldimagery": ipyleaflet.basemaps.Esri.WorldImagery, |
27 | | - "worldstreetmap": ipyleaflet.basemaps.Esri.WorldStreetMap, |
28 | | - "worldtopomap": ipyleaflet.basemaps.Esri.WorldTopoMap, |
| 21 | +# Candidate basemap abbreviations — loaded lazily to avoid import failures |
| 22 | +# if a provider has been decommissioned upstream. |
| 23 | +_basemap_abbrev_candidates = { |
| 24 | + "mapnik": lambda: ipyleaflet.basemaps.OpenStreetMap.Mapnik, |
| 25 | + "natgeoworldmap": lambda: ipyleaflet.basemaps.Esri.NatGeoWorldMap, |
| 26 | + "opentopomap": lambda: ipyleaflet.basemaps.OpenTopoMap, |
| 27 | + "positron": lambda: ipyleaflet.basemaps.CartoDB.Positron, |
| 28 | + "satellite": lambda: ipyleaflet.basemaps.Gaode.Satellite, |
| 29 | + "worldimagery": lambda: ipyleaflet.basemaps.Esri.WorldImagery, |
| 30 | + "worldstreetmap": lambda: ipyleaflet.basemaps.Esri.WorldStreetMap, |
| 31 | + "worldtopomap": lambda: ipyleaflet.basemaps.Esri.WorldTopoMap, |
29 | 32 | } |
30 | 33 |
|
| 34 | +_basemap_abbrevs: dict | None = None |
| 35 | + |
| 36 | + |
| 37 | +def get_basemap_abbrevs() -> dict: |
| 38 | + """Return available basemap abbreviations, skipping any unavailable providers.""" |
| 39 | + global _basemap_abbrevs |
| 40 | + if _basemap_abbrevs is None: |
| 41 | + _basemap_abbrevs = {} |
| 42 | + for key, provider_fn in _basemap_abbrev_candidates.items(): |
| 43 | + try: |
| 44 | + _basemap_abbrevs[key] = provider_fn() |
| 45 | + except Exception: |
| 46 | + warnings.warn( |
| 47 | + f"Basemap provider {key!r} is not available and will be skipped.", |
| 48 | + stacklevel=2, |
| 49 | + ) |
| 50 | + return _basemap_abbrevs |
| 51 | + |
| 52 | + |
| 53 | +# Keep basemap_abbrevs as a property-like alias for backwards compatibility. |
| 54 | +# Code that does `map_params.basemap_abbrevs` will call get_basemap_abbrevs(). |
| 55 | +class _BasemapAbbrevProxy: |
| 56 | + def __getattr__(self, item): |
| 57 | + return getattr(get_basemap_abbrevs(), item) |
| 58 | + |
| 59 | + def __iter__(self): |
| 60 | + return iter(get_basemap_abbrevs()) |
| 61 | + |
| 62 | + def __getitem__(self, item): |
| 63 | + return get_basemap_abbrevs()[item] |
| 64 | + |
| 65 | + def __contains__(self, item): |
| 66 | + return item in get_basemap_abbrevs() |
| 67 | + |
| 68 | + def keys(self): |
| 69 | + return get_basemap_abbrevs().keys() |
| 70 | + |
| 71 | + def values(self): |
| 72 | + return get_basemap_abbrevs().values() |
| 73 | + |
| 74 | + def items(self): |
| 75 | + return get_basemap_abbrevs().items() |
| 76 | + |
| 77 | + |
| 78 | +basemap_abbrevs = _BasemapAbbrevProxy() |
| 79 | + |
31 | 80 | basemap: TypeAlias = Annotated[ |
32 | 81 | Union[str, Dict, ipyleaflet.TileLayer, xyzservices.lib.TileProvider], |
33 | 82 | f""" |
34 | 83 | Basemap from ipyleaflet or other TileLayer provider. Strings are abbreviations mapped to corresponding |
35 | | - basemaps, available values are {list(basemap_abbrevs.keys())}. |
| 84 | + basemaps, available values are {list(_basemap_abbrev_candidates.keys())}. |
36 | 85 | """, |
37 | 86 | ] |
38 | 87 |
|
|
0 commit comments