Earth Coordinate Conversion#

In this tutorial, we will show how to place actors on specific locations on the surface of the Earth using a new function.

```import itertools
import math

import numpy as np

from fury import actor, io, utils, window
```

Create a new scene, and load in the image of the Earth using `fetch_viz_textures` and `read_viz_textures`. We will use a 16k resolution texture for maximum detail.

```scene = window.Scene()

fetch_viz_textures()
earth_actor = actor.texture_on_sphere(earth_image)
```
```Dataset is already in place. If you want to fetch it again please first remove the folder /Users/skoudoro/.fury/textures
/opt/homebrew/Caskroom/miniforge/base/envs/fury-39-x86/lib/python3.9/site-packages/PIL/Image.py:3167: DecompressionBombWarning: Image size (131220000 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
warnings.warn(
```

Rotate the Earth to make sure the texture is correctly oriented. Change it’s scale using `actor.SetScale()`.

```utils.rotate(earth_actor, (-90, 1, 0, 0))
utils.rotate(earth_actor, (180, 0, 1, 0))
earth_actor.SetScale(2, 2, 2)
```

Define the function to convert geographical coordinates of a location in latitude and longitude degrees to coordinates on the `earth_actor` surface. In this function, convert to radians, then to spherical coordinates, and lastly, to cartesian coordinates.

```def latlong_coordinates(lat, lon):
# Convert latitude and longitude to spherical coordinates
# phi = 90 - latitude
phi = (90 - lat) * degrees_to_radians
# theta = longitude
theta = lon * degrees_to_radians * -1
# now convert to cartesian
x = np.sin(phi) * np.cos(theta)
y = np.sin(phi) * np.sin(theta)
z = np.cos(phi)
# flipping z to y for FURY coordinates
return (x, z, y)
```

Use this new function to place some sphere actors on several big cities around the Earth.

```locationone = latlong_coordinates(40.730610, -73.935242)  # new york city, us
locationtwo = latlong_coordinates(39.916668, 116.383331)  # beijing, china
locationthree = latlong_coordinates(48.864716, 2.349014)  # paris, france
```

Set the centers, radii, and colors of these spheres, and create a new `sphere_actor` for each location to add to the scene.

```centers = np.array([[*locationone], [*locationtwo], [*locationthree]])
colors = np.random.rand(3, 3)
```

Create some text actors to add to the scene indicating each location and its geographical coordinates.

```nyc_actor = actor.text_3d(
'New York City, New York\n40.7128° N, 74.0060° W',
(locationone[0] - 0.04, locationone[1], locationone[2] + 0.07),
window.colors.white,
0.01,
)
paris_actor = actor.text_3d(
'Paris, France\n48.8566° N, 2.3522° E',
(locationthree[0] - 0.04, locationthree[1], locationthree[2] - 0.07),
window.colors.white,
0.01,
)
beijing_actor = actor.text_3d(
'Beijing, China\n39.9042° N, 116.4074° E',
(locationtwo[0] - 0.06, locationtwo[1], locationtwo[2] - 0.07),
window.colors.white,
0.01,
)
utils.rotate(paris_actor, (85, 0, 1, 0))
utils.rotate(beijing_actor, (180, 0, 1, 0))
utils.rotate(nyc_actor, (5, 1, 0, 0))
```

Create a ShowManager object, which acts as the interface between the scene, the window and the interactor.

```showm = window.ShowManager(
scene, size=(900, 768), reset_camera=False, order_transparent=True
)
```

Let’s create a `timer_callback` function to add some animation to the Earth. Change the camera position and angle to fly over and zoom in on each new location.

```counter = itertools.count()

def timer_callback(_obj, _event):
cnt = next(counter)
showm.render()
if cnt == 0:
scene.set_camera(position=(1.5, 3.5, 7.0))
if cnt < 200 and cnt > 25:
scene.zoom(1.015)
scene.pitch(0.01)
if cnt == 200:
if cnt > 250 and cnt < 350:
scene.zoom(0.985)
if cnt > 350 and cnt < 425:
scene.azimuth(1)
if cnt > 425 and cnt < 525:
scene.zoom(1.015)
scene.pitch(0.011)
if cnt == 525:
if cnt > 575 and cnt < 700:
scene.zoom(0.985)
if cnt > 700 and cnt < 820:
scene.azimuth(1)
if cnt > 820 and cnt < 930:
scene.zoom(1.015)
if cnt == 930:
if cnt == 1000:
showm.exit()
```

Initialize the ShowManager object, add the timer_callback, and watch the new animation take place!

```showm.add_timer_callback(True, 25, timer_callback)
showm.start()

window.record(showm.scene, size=(900, 768), out_path='viz_earth_coordinates.png')
```

Total running time of the script: ( 0 minutes 29.020 seconds)

Gallery generated by Sphinx-Gallery