Where is the International Space Station?

This map tracks the real time position of the International Space Station (ISS). It updates every 15 seconds.

Home

Fanny Kassapian
2019/06/05

Arrow

Who's up there?

The ISS is the largest human-made body in low Earth orbit. It has been inhabited continously since November 2000. It currently counts ? residents:

Data

All the data used to produce this map is retrieved dynamically thanks to the Open Notify APIs, a collection of NASA and space APIs for public use, developped by Nathan Bergey.

The country, sea or ocean names corresponding to the latitude and longitude coordinates returned by Open Notify are retrieved via the GeoNames APIs. The GeoNames geographical database covers all countries and contains over eleven million placenames that can be downloaded or accessed via their web services.

Code

The source code behind this project (HTML, CSS, jQuery, JavaScript), can be found in my GitHub repository (iss.html).
For the same in Python, please refer to this Notebook (GitHub).

Map

The map is built with Leaflet.js. For a basic setup, you can follow their quick start guide.

I used the World Imagery Basemap from ESRI as a tile layer on top of the map. All the free tile providers along with previews of the layers are available here.
I used a custom image (hand drawn with procreate) for the ISS marker, on top of a larger circle marker.

The map and markers are initialized with [0,0] coordinates. These are updated with the latitude and longitude returned by the iss-now.json endpoint of the Open Notify API.

Open Notify

In these examples, Open Notify provides jQuery primers to make requests to its APIs.

GeoNames

I used the countrycode and ocean REST webservices to retrieve the country name or ocean/sea name of a given set of coordinates.

GeoNames data is free. The credit daily limit per application (identified by the parameter 'username') is of 20,000 requests. The hourly limit is of 1,000 requests.

The countryCode API takes the following parameters: lat (latitude), lng (longitude), type, lang, radius (buffer in km for closest country in coastal areas. Lang (to specify the language the country name should be in) and type (JSON or XML) are optional.

When we make a request to countrycode, the API returns a JSON with the countryCode, countryName, distance and languages as keys. If the API does not find a country name corresponding to the given set of coordinates, it returns the following: {'status': {'message': 'no country code found', 'value': 15}}. Which is bound to happen a lot, since only 29% of Earth is land...

In this case, we make a request to the ocean API. It takes lat, lng and radius (optional) as parameters. It returns a JSON with ocean as key, and a nested dictionary with distance and name as keys.
Again, we have to make sure that this is the actual response we get from the API (without raising an error), and if not, return a custom message to the user. Either the API cannot retrieve the corresponding country/ocean name based on the given coordinates, or the application has reached the rate limit.


          // Request parameters
          var parameters = {'lat': lat, 'lng': lon, 'type': 'JSON', 'radius':50, 'username':'user'};
          // Request to countryCode endpoint
          $.getJSON('http://api.geonames.org/countryCode?', parameters, function(data) {

              // Initialize country variable
              var country = '';
              // Check if 'countryName' is a key in API response
              if ('countryName' in data) {
                // Extract value
                country = data['countryName'];
                // Update html
                $("#country").html('The ISS is above ' + country + '!');
              }

              // If 'countryName' is NOT a key in data, make a request to the Ocean endpoint
              else {
                // Request parameters
                var parameters = {'lat': lat, 'lng': lon, 'radius':1, 'username':'user'};
                // Request to Ocean endpoint
                $.getJSON('http://api.geonames.org/oceanJSON?', parameters, function(data) {

                  // Create ocean variable
                  var ocean = '';
                  // Check if 'ocean' is a key in API response
                  if ('ocean' in data) {
                    // Extract value
                    ocean = data['ocean']['name'];
                    // Update html
                    $("#country").html('The ISS is above the '+ ocean + '!');
                  }
                  // If the API response does not include 'ocean' as a key, return an error message
                  else {
                    $("#country").html("Oups! It looks like the GeoNames API is not responding.");
                  }

                });
              }

          });