-
-
Notifications
You must be signed in to change notification settings - Fork 389
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
500 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }; |
Oops, something went wrong.