diff --git a/docs/maplibre/3d_terrain.ipynb b/docs/maplibre/3d_terrain.ipynb index c7ca817566..99e81b52e1 100644 --- a/docs/maplibre/3d_terrain.ipynb +++ b/docs/maplibre/3d_terrain.ipynb @@ -33,6 +33,22 @@ "import leafmap.maplibregl as leafmap" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To run this notebook, you will need an [API key](https://docs.maptiler.com/cloud/api/authentication-key/) from [MapTiler](https://www.maptiler.com/cloud/). Once you have the API key, you can set it as an environment variable in your notebook or script as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# os.environ[\"MAPTILER_KEY\"] = \"YOUR_API_KEY\"" + ] + }, { "cell_type": "code", "execution_count": null, @@ -90,6 +106,25 @@ "source": [ "![](https://i.imgur.com/sjXZ2Jm.jpeg)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m = leafmap.Map(\n", + " center=[-122.19861, 46.21168], zoom=13, pitch=60, bearing=150, style=\"3d-terrain\"\n", + ")\n", + "m" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![](https://i.imgur.com/jALOara.png)" + ] } ], "metadata": { diff --git a/docs/maplibre/live_update_feature.ipynb b/docs/maplibre/live_update_feature.ipynb index 28c0749e02..29227507f6 100644 --- a/docs/maplibre/live_update_feature.ipynb +++ b/docs/maplibre/live_update_feature.ipynb @@ -38,16 +38,29 @@ "import leafmap.maplibregl as leafmap" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To run this notebook, you will need an [API key](https://docs.maptiler.com/cloud/api/authentication-key/) from [MapTiler](https://www.maptiler.com/cloud/). Once you have the API key, you can set it as an environment variable in your notebook or script as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# os.environ[\"MAPTILER_KEY\"] = \"YOUR_API_KEY\"" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "m = leafmap.Map(\n", - " center=(-122.019807, 45.632433), zoom=14, pitch=30, style=\"background-gray\"\n", - ")\n", - "m.add_basemap(\"Google Hybrid\")\n", + "m = leafmap.Map(center=[-122.019807, 45.632433], zoom=14, pitch=60, style=\"3d-terrain\")\n", "m" ] }, @@ -105,7 +118,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![](https://i.imgur.com/zEU8lbu.png)" + "![](https://i.imgur.com/FPB5j6V.png)" ] } ], @@ -125,7 +138,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.8" } }, "nbformat": 4, diff --git a/docs/maplibre/overview.md b/docs/maplibre/overview.md index 5798ce2eb6..fdf7ebd6d0 100644 --- a/docs/maplibre/overview.md +++ b/docs/maplibre/overview.md @@ -90,7 +90,7 @@ Use the line-gradient paint property and an expression to visualize distance fro Change an existing feature on your map in real-time by updating its data. -[![](https://i.imgur.com/zEU8lbu.png)](https://leafmap.org/maplibre/live_update_feature) +[![](https://i.imgur.com/FPB5j6V.png)](https://leafmap.org/maplibre/live_update_feature) ## Add live realtime data diff --git a/leafmap/maplibregl.py b/leafmap/maplibregl.py index 18324be084..1c6a52e68d 100644 --- a/leafmap/maplibregl.py +++ b/leafmap/maplibregl.py @@ -92,6 +92,8 @@ def __init__( elif "background-" in style: color = style.split("-")[1] style = background(color) + elif style == "3d-terrain": + style = self._get_3d_terrain_style() if style is not None: kwargs["style"] = style @@ -1611,3 +1613,73 @@ def jump_to(self, options: Dict[str, Any] = {}, **kwargs: Any) -> None: None """ super().add_call("jumpTo", options, **kwargs) + + def _get_3d_terrain_style( + self, + exaggeration: float = 1, + 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: + exaggeration (float, optional): The terrain exaggeration. Defaults to 1. + 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_api_key(token) + + if api_key is None: + raise ValueError("An API key is required to use the 3D terrain feature.") + + style = { + "version": 8, + "sources": { + "satellite": { + "type": "raster", + "tiles": [ + "https://api.maptiler.com/tiles/satellite-v2/{z}/{x}/{y}.jpg?key=" + + api_key + ], + "tileSize": 256, + "attribution": "© MapTiler", + "maxzoom": 19, + }, + "terrainSource": { + "type": "raster-dem", + "url": f"https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key={api_key}", + "tileSize": 256, + }, + "hillshadeSource": { + "type": "raster-dem", + "url": f"https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key={api_key}", + "tileSize": 256, + }, + }, + "layers": [ + {"id": "satellite", "type": "raster", "source": "satellite"}, + { + "id": "hills", + "type": "hillshade", + "source": "hillshadeSource", + "layout": {"visibility": "visible"}, + "paint": {"hillshade-shadow-color": "#473B24"}, + }, + ], + "terrain": {"source": "terrainSource", "exaggeration": exaggeration}, + } + + return style