Skip to content

Commit

Permalink
Add support for Mapbox (#841)
Browse files Browse the repository at this point in the history
  • Loading branch information
giswqs authored Jul 21, 2024
1 parent e47a82b commit 654c12e
Show file tree
Hide file tree
Showing 7 changed files with 500 additions and 0 deletions.
307 changes: 307 additions & 0 deletions docs/notebooks/94_mapbox.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"[![image](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://demo.leafmap.org/lab/index.html?path=notebooks/94_mapbox.ipynb)\n",
"[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/opengeos/leafmap/blob/master/examples/notebooks/94_mapbox.ipynb)\n",
"[![image](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/opengeos/leafmap/HEAD)\n",
"\n",
"**Creating 3D maps with Mapbox**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# %pip install -U leafmap"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import leafmap.mapbox as leafmap"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"You need a Mapbox access token to use the Mapbox widget. First, [sign up](https://account.mapbox.com/auth/signup/) for a free Mapbox account. Then, you can create a token by following the instructions [here](https://docs.mapbox.com/api/accounts/tokens/). Set `Mapbox_TOKEN` as an environment variable to use the Mapbox widget. Alternatively, uncomment the following code block and replace `YOUR-API-TOKEN` with your Mapbox access token."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# import os\n",
"# os.environ['MAPBOX_TOKEN'] = 'YOUR-API-TOKEN'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m = leafmap.Map(center=[-100, 40], zoom=1.2, height=\"600px\")\n",
"m"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"![](https://i.imgur.com/1PbtnQE.gif)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m = leafmap.Map(style=\"mapbox://styles/mapbox/satellite-streets-v12\")\n",
"m"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.clicked_lnglat"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.zoom"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.center"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.bounds"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"esm = \"\"\"\n",
"\n",
" const map = new mapboxgl.Map({\n",
" container: 'map',\n",
" zoom: 14,\n",
" center: [-114.26608, 32.7213],\n",
" pitch: 80,\n",
" bearing: 41,\n",
" // Choose from Mapbox's core styles, or make your own style with Mapbox Studio\n",
" style: 'mapbox://styles/mapbox/satellite-streets-v12'\n",
" });\n",
"\n",
" map.on('style.load', () => {\n",
" map.addSource('mapbox-dem', {\n",
" 'type': 'raster-dem',\n",
" 'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',\n",
" 'tileSize': 512,\n",
" 'maxzoom': 14\n",
" });\n",
" // add the DEM source as a terrain layer with exaggerated height\n",
" map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 });\n",
" });\n",
"\n",
"\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.set_esm(esm)\n",
"m"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"![](https://i.imgur.com/xvdrvpx.png)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"esm = \"\"\"\n",
"\n",
" (async () => {\n",
" const map = new mapboxgl.Map({\n",
" container: 'map',\n",
" zoom: 13,\n",
" center: [6.6301, 45.35625],\n",
" pitch: 80,\n",
" bearing: 160,\n",
" interactive: false,\n",
" // Choose from Mapbox's core styles, or make your own style with Mapbox Studio\n",
" style: 'mapbox://styles/mapbox/satellite-v9'\n",
" });\n",
"\n",
" await map.once('style.load');\n",
"\n",
" // Add daytime fog\n",
" map.setFog({\n",
" 'range': [-1, 2],\n",
" 'horizon-blend': 0.3,\n",
" 'color': 'white',\n",
" 'high-color': '#add8e6',\n",
" 'space-color': '#d8f2ff',\n",
" 'star-intensity': 0.0\n",
" });\n",
"\n",
" // Add 3D terrain\n",
" map.addSource('mapbox-dem', {\n",
" 'type': 'raster-dem',\n",
" 'url': 'mapbox://mapbox.terrain-rgb',\n",
" 'tileSize': 512,\n",
" 'maxzoom': 14\n",
" });\n",
" map.setTerrain({\n",
" 'source': 'mapbox-dem',\n",
" 'exaggeration': 1.5\n",
" });\n",
"\n",
" // Run a timing loop to switch between day and night\n",
" await map.once('idle');\n",
"\n",
" let lastTime = 0.0;\n",
" let animationTime = 0.0;\n",
" let cycleTime = 0.0;\n",
" let night = true;\n",
"\n",
" const initialBearing = map.getBearing();\n",
"\n",
" function frame(time) {\n",
" const elapsedTime = (time - lastTime) / 1000.0;\n",
"\n",
" animationTime += elapsedTime;\n",
" cycleTime += elapsedTime;\n",
"\n",
" if (cycleTime >= 10.0) {\n",
" if (night) {\n",
" // night fog styling\n",
" map.setFog({\n",
" 'range': [-1, 2],\n",
" 'horizon-blend': 0.3,\n",
" 'color': '#242B4B',\n",
" 'high-color': '#161B36',\n",
" 'space-color': '#0B1026',\n",
" 'star-intensity': 0.8\n",
" });\n",
" } else {\n",
" // day fog styling\n",
" map.setFog({\n",
" 'range': [-1, 2],\n",
" 'horizon-blend': 0.3,\n",
" 'color': 'white',\n",
" 'high-color': '#add8e6',\n",
" 'space-color': '#d8f2ff',\n",
" 'star-intensity': 0.0\n",
" });\n",
" }\n",
"\n",
" night = !night;\n",
" cycleTime = 0.0;\n",
" }\n",
"\n",
" const rotation = initialBearing + animationTime * 2.0;\n",
" map.setBearing(rotation % 360);\n",
"\n",
" lastTime = time;\n",
"\n",
" window.requestAnimationFrame(frame);\n",
" }\n",
"\n",
" window.requestAnimationFrame(frame);\n",
" })();\n",
"\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m.set_esm(esm)\n",
"m"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"![](https://i.imgur.com/ZRRUK3v.png)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.8"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
1 change: 1 addition & 0 deletions docs/tutorials.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
91. Visualizing raster data interactively ([notebook](https://leafmap.org/notebooks/91_raster_viz_gui))
92. Creating 3D maps with the MapLibre mapping backend ([notebook](https://leafmap.org/notebooks/92_maplibre))
93. Visualizing PMTiles with Leafmap and MapLibre ([notebook](https://leafmap.org/notebooks/93_maplibre_pmtiles))
94. Creating 3D maps with Mapbox ([notebook](https://leafmap.org/notebooks/94_mapbox))

## Demo

Expand Down
63 changes: 63 additions & 0 deletions leafmap/javascript/mapbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import mapboxgl from "https://esm.sh/[email protected]";

function render({ model, el }) {
// Header
let center = model.get("center");
let zoom = model.get("zoom");
let width = model.get("width");
let height = model.get("height");
let style = model.get("style");

const div = document.createElement("div");
div.style.width = width;
div.style.height = height;

let token = model.get("token");
mapboxgl.accessToken = token;

// Map content

const map = new mapboxgl.Map({
container: div,
style: style,
center: center,
zoom: zoom,
});

map.on("click", function (e) {
model.set("clicked_lnglat", [e.lngLat.lng, e.lngLat.lat]);
model.save_changes();
});

map.on("moveend", function (e) {
model.set("center", [map.getCenter().lng, map.getCenter().lat]);
let bbox = map.getBounds();
let bounds = [bbox._sw.lng, bbox._sw.lat, bbox._ne.lng, bbox._ne.lat];
model.set("bounds", bounds);
model.save_changes();
});

map.on("zoomend", function (e) {
model.set("center", [map.getCenter().lng, map.getCenter().lat]);
model.set("zoom", map.getZoom());
let bbox = map.getBounds();
let bounds = [bbox._sw.lng, bbox._sw.lat, bbox._ne.lng, bbox._ne.lat];
model.set("bounds", bounds);
model.save_changes();
});

// model.on("change:center", function () {
// let center = model.get("center");
// center.reverse();
// map.setCenter(center);
// });

// model.on("change:zoom", function () {
// let zoom = model.get("zoom");
// map.setZoom(zoom);
// });

// Footer
el.appendChild(div);
}
export default { render };
Loading

0 comments on commit 654c12e

Please sign in to comment.