Getting the current location of the ISS is actually super easy. There's a very simple Open Notify API Server which provides a couple of data sources:
The one we'll use is...you guessed it...the one called ISS Location Now. That links to a simple JSON result which gives the current ISS location in terms of latitude and longitude.
The only problem is that latitude and longitude coordinates (lat, lon) describe the location in terms of a spherical coordinate system, since the Earth is round. We want to convert that to a 2D (x, y) location on a flat surface, like the PyPortal display. This is the realm of map projections. There are quite a few, a lot of which are not rectangular. We'll just stick with the classic Mercator projection.
So how do we convert the (lat, lon) coordinates provided by the web service into (x, y) coordinates we can display on our PyPortal? It's basically the same math that is used in the map transform.
You can find it for the Mercator projection on the page linked above. It's kind of buried in there with a bunch of others, but the main one to focus on is the one in terms of map width (W):
Instead of map width, this will be our display width. The other symbols are:
- W = display width (320 for PyPortal)
- λ = longitude in radians
- φ = latitude in radians
- π = Pi (a constant)
We know our display width W. And π is a known constant (3.1415etc). The λo is just an offset for the horizontal origin. So then we can take any (lat, lon) = (φ, λ) pair and compute the corresponding (x, y) location for the PyPortal display.
This stackoverflow post also has some good information.
The math above works almost all the way to the North and South poles. But the ISS has an orbital inclination of 51.6°, so we don't need to worry about latitudes above that. This works out nicely as it let's us crop our map a little at the top and bottom, which makes it fit better on the PyPortal display.
So, let's get a map. The one used on the same Wikipedia page linked above will work fine.
And now we want to crop this map to fit the PyPortal screen, which is 320 x 240 pixels. You can do this in image manipulation software like Photoshop or Gimp. The red dashed rectangle below represents our crop which has an aspect ratio of 320:240 and uses the entire width of the map.
After cropping, we end up with this:
Then we just scale it so it's 320 x 240 pixels and save it as a BMP files so we can load it with the CircuitPython displayio library.
Here's the final file: