Cesium 3D Globe Example¶
This notebook demonstrates the capabilities of the anymap CesiumMap widget for creating interactive 3D globe visualizations.
Setup¶
First, make sure you have a Cesium ion access token. You can get a free one at https://cesium.com/ion/signup
import os
from anymap import CesiumMap
# Set your Cesium token (get a free one at https://cesium.com/ion/signup)
# You can either set it as an environment variable CESIUM_TOKEN or pass it directly
# os.environ['CESIUM_TOKEN'] = 'your_token_here'
print("Cesium backend loaded successfully!")
Cesium backend loaded successfully!
Basic 3D Globe¶
Create a basic 3D globe centered on a specific location:
from anymap import CesiumMap
# Create a basic Cesium map centered on New York City
globe = CesiumMap(
center=[40.7128, -74.0060], # NYC coordinates
camera_height=2000000, # 2000 km above surface
width="100%",
height="600px",
navigation_help_button=False,
)
globe
/home/runner/work/anymap/anymap/anymap/anymap.py:1034: UserWarning: No Cesium access token found. Please set CESIUM_TOKEN environment variable or pass access_token parameter. Get a free token at https://cesium.com/ion/signup warnings.warn(
Adding Points and Markers¶
Add various points and billboards to the globe:
# Add some famous landmarks as points
globe.add_point(
40.7128,
-74.0060,
height=200000, # 200 km above NYC
name="New York City",
description="The Big Apple",
color="#ff0000",
pixel_size=20,
)
globe.add_point(
51.5074,
-0.1278,
height=150000, # 150 km above London
name="London",
description="Capital of England",
color="#0000ff",
pixel_size=15,
)
globe.add_point(
35.6762,
139.6503,
height=100000, # 100 km above Tokyo
name="Tokyo",
description="Capital of Japan",
color="#00ff00",
pixel_size=18,
)
print("Added landmark points to the globe!")
Added landmark points to the globe!
Camera Controls and Navigation¶
Demonstrate camera movement and positioning:
# Fly to different locations with smooth transitions
globe.fly_to(
51.5074,
-0.1278, # London
height=5000000, # 5000 km above
duration=3.0,
heading=45,
pitch=-30,
)
print("Flying to London...")
Flying to London...
# Fly to Tokyo with different camera angle
globe.fly_to(
35.6762,
139.6503, # Tokyo
height=3000000, # 3000 km above
duration=4.0,
heading=90,
pitch=-45,
)
print("Flying to Tokyo...")
Flying to Tokyo...
Adding 3D Geometries¶
Add polylines and polygons to show connections and regions:
# Add a flight path polyline from NYC to London
flight_path = [
[40.7128, -74.0060, 10000], # NYC at 10km altitude
[45.0, -30.0, 12000], # Midpoint over Atlantic
[51.5074, -0.1278, 10000], # London at 10km altitude
]
globe.add_polyline(
flight_path,
width=3,
color="#ffff00",
name="NYC to London Flight Path",
description="Transatlantic flight route",
)
print("Added flight path polyline!")
Added flight path polyline!
# Add a polygon area around the Mediterranean Sea
mediterranean_bounds = [
[30.0, -6.0, 0], # Gibraltar area
[30.0, 36.0, 0], # Eastern Mediterranean
[46.0, 36.0, 0], # Turkey area
[46.0, -6.0, 0], # Spain area
[30.0, -6.0, 0], # Close the polygon
]
globe.add_polygon(
mediterranean_bounds,
color="rgba(0, 100, 255, 0.3)", # Semi-transparent blue
outline_color="#0064ff",
name="Mediterranean Region",
description="Mediterranean Sea region",
)
print("Added Mediterranean polygon!")
Added Mediterranean polygon!
Working with GeoJSON Data¶
Load and display GeoJSON data on the globe:
# Sample GeoJSON data with world capitals
world_capitals_geojson = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-77.0369, 38.9072], # Washington DC
},
"properties": {
"name": "Washington DC",
"country": "USA",
"population": 705749,
},
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [2.3522, 48.8566]}, # Paris
"properties": {"name": "Paris", "country": "France", "population": 2161000},
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.4074, 39.9042], # Beijing
},
"properties": {
"name": "Beijing",
"country": "China",
"population": 21540000,
},
},
],
}
# Add GeoJSON data to the globe
globe.add_geojson(
world_capitals_geojson, options={"name": "World Capitals", "clampToGround": True}
)
print("Added world capitals GeoJSON data!")
Added world capitals GeoJSON data!
Terrain and Imagery¶
Configure terrain and satellite imagery:
# Enable Cesium World Terrain for realistic 3D terrain
globe.set_cesium_world_terrain(request_water_mask=True, request_vertex_normals=True)
print("Enabled Cesium World Terrain!")
Enabled Cesium World Terrain!
# Switch to satellite imagery (requires Bing Maps key for best results)
# You can get a Bing Maps key at https://www.bingmapsportal.com/
globe.set_imagery(
{
"type": "osm", # Using OpenStreetMap as fallback
"url": "https://tile.openstreetmap.org/",
}
)
print("Changed to OpenStreetMap imagery!")
Changed to OpenStreetMap imagery!
Scene Modes and Effects¶
Experiment with different viewing modes and atmospheric effects:
# Enable atmospheric effects
globe.enable_lighting(True)
globe.enable_fog(True)
print("Enabled lighting and atmospheric fog!")
Enabled lighting and atmospheric fog!
# Switch to 2D mode for flat map view
globe.set_scene_mode_2d()
print("Switched to 2D mode!")
Switched to 2D mode!
# Switch to Columbus view (2.5D)
globe.set_scene_mode_columbus()
print("Switched to Columbus view!")
Switched to Columbus view!
# Back to full 3D mode
globe.set_scene_mode_3d()
print("Switched back to 3D mode!")
Switched back to 3D mode!
Event Handling¶
Set up event handlers to respond to user interactions:
# Define event handler functions
def on_click(event):
print(
f"Globe clicked at: Lat {event['latitude']:.4f}, Lon {event['longitude']:.4f}, Height {event['height']:.0f}m"
)
if event.get("pickedObject"):
print(f"Clicked on object: {event['pickedObject']}")
def on_camera_move(event):
print(
f"Camera moved to: Lat {event['latitude']:.4f}, Lon {event['longitude']:.4f}, Height {event['height']:.0f}m"
)
# Register event handlers
globe.on_map_event("click", on_click)
globe.on_map_event("moveend", on_camera_move)
print("Event handlers registered! Click on the globe or move the camera to see events.")
Event handlers registered! Click on the globe or move the camera to see events.
Multi-cell Rendering Test¶
Test that the globe works correctly when displayed in multiple cells:
# Display the same globe instance again
# This should maintain all the data and state from above
globe
# Add another point while displayed in multiple cells
globe.add_point(
-33.8688,
151.2093, # Sydney
height=500000,
name="Sydney",
description="Largest city in Australia",
color="#ff8800",
pixel_size=16,
)
print("Added Sydney! The point should appear on all globe instances above.")
Added Sydney! The point should appear on all globe instances above.
Creating a Second Globe Instance¶
Create a separate globe to verify independence:
# Create a second, independent globe
globe2 = CesiumMap(
center=[-33.8688, 151.2093], # Centered on Sydney
camera_height=1000000, # 1000 km above
width="100%",
height="500px",
timeline=False, # Disable timeline for cleaner look
animation=False, # Disable animation controls
)
# Add different content to the second globe
globe2.add_point(
-33.8688,
151.2093,
height=50000,
name="Sydney Opera House Area",
color="#9900ff",
pixel_size=25,
)
globe2.add_point(
-37.8136,
144.9631, # Melbourne
height=40000,
name="Melbourne",
color="#00ffff",
pixel_size=20,
)
globe2
Reset and Home View¶
Return to the home view:
# Reset camera to home position
globe.home()
print("Camera reset to home position!")
Camera reset to home position!
Summary¶
This notebook demonstrated the key features of the anymap CesiumMap widget:
- 3D Globe Visualization: Interactive 3D globe with realistic Earth rendering
- Points and Markers: Adding labeled points at various heights
- 3D Geometries: Polylines and polygons for paths and regions
- GeoJSON Support: Loading external geographic data
- Terrain and Imagery: Realistic 3D terrain and satellite imagery
- Scene Modes: 3D, 2D, and Columbus view modes
- Camera Controls: Smooth fly-to animations and positioning
- Event Handling: Responding to user interactions
- Multi-cell Rendering: Persistent state across notebook cells
- Multiple Instances: Independent globe widgets
The CesiumMap widget provides a powerful platform for creating interactive 3D geospatial visualizations with the full capabilities of Cesium.js in a Jupyter environment.