The International Space Station is a large spacecraft orbiting around Earth. It is a home where astronauts live, a laboratory and a port for international spacecraft.

The ISS orbits at approximately 220 miles (350 km) above the Earth making multiple orbits around the Earth every day. It travels at an average speed of 17,227 miles (27,724 km) per hour.

As it is moving so fast in the sky, it’s tough to be sure of its location. But with scriptr.io WE CAN TRACK ITS ORBIT.

Are you ready to track the ISS? Let’s go.

In this blog, I will focus on demonstrating how to display broadcasted geolocation data in realtime using:

In a nutshell the following diagram explains the process. Luckily, I do not have to code it all from scratch. I will fork a previous scriptr.io implementation of  Geolocation Mapping available on github.

ISS Diagram 3

I will pull out the GeoLocation Mapping sample code I forked into my scriptr.io account repository.

GeoMapping Sample

A set of scripts will be added to the tree under the Maps folder. All the files and scripts should be marked as anonymous.

Following the diagram steps, I will add a channel named ISSGeoLocation with anonymous publishing & subscription.

create-channel

How do we load the ISS geolocation info? Pretty easy!  http://api.open-notify.org/iss-now.json  is a simple api to return the current latitude and longitude of the ISS with a UNIX timestamp for the time the location was valid.

{
   "iss_position": {
   "latitude": 21.4629064100921,
   "longitude": 169.15544045616028
},
"message": "success",
"timestamp": 1465986087
}

To the previously pulled “Maps” scripts structure I will add a new script “generateIssLiveData” under”Maps/scripts”. In this script I will make use of the scriptr.io http request module to fetch the data from the open-notify iss-now api.

From the http request response I will build an object [{lat: xxxx, lng:yyyy}] and  publish this object to the ISSGeoLocation channel.

var http = require("http");
//Internationa Station Location api
var issLocationUrl = "http://api.open-notify.org/iss-now.json";

// invoke the third party API
var callResult = http.request({"url":issLocationUrl});

/**
parse the response of the call
{
"message": "success",
"timestamp": UNIX_TIME_STAMP,
"iss_position": {
"latitude": CURRENT_LATITUDE,
"longitude": CURRENT_LONGITUDE
}
}
using regular JSON object
**/

var entry = JSON.parse(callResult.body)["iss_position"];

var x = {lat: parseFloat(entry.latitude), lng: parseFloat(entry.longitude)};

//Publish GeoLocation to ISSLocationChannel
publish('ISSGeoLocation',[x], false);

 

To have the GeoLocation of the ISS broadcasted over my ISSGeoLocation channel in real time, we will use the scriptr.io schedule function in order for the “Maps/scripts/generateIssLiveData” script to run every minute (i.e. every 1 minute, the ISS now location will be published to the ISSGeoLocation channel).

schedule-script

Since I am using the geolocation-mapping repository scripts as a base for my project, I don’t need to worry about writing a Websocket client javascript class or building the HTML file for the map.

I will use the existing “Maps/static/wsClient.js” file script as my WebSocket client  & “Maps/html/live.html” as my project entry point.

I edit the “Maps/static/config.js” to set the values:

  1. scriptr.io WebSocket connection parameters:
    • url value is my scriptr.io real time url with anonymous token.
  2. the channel over which the geo data will be broadcasted to the browser:
    • receive_channel will be “ISSGeoLocation”, the channel I created previously.
    websocket: {
       url: "wss://api.scriptrapps.io/RTg2MTczN0ZDRQ==",
       receive_channel: "ISSGeoLocation"//The Channel name to which the live GPS data will be  pushed, and to which the client websocket will subscribe
    }
  • Google maps browser api key:
     map: {
      	key: "AIzaSyBcPYghFh_BXz4dDz-TXTHbU2iV3Wbf57I", //https://developers.google.com/maps/documentation/javascript/get-api-key#get-an-api-key
    

    I acquired my key by following the google maps tutorial.

  • dataHandler transformFnc value:
    dataHandler: {
        transformFnc:  "addSpaceStationPoint" // //Define the transformation function you will use. ex: "renderEarthquakeGeoLocations", "renderRandomGeoLocations" 
    }
    

    transformFnc holds the name of the data handling function that I will implement next. It is used to parse the GeoLocation message received over the WebSocket and transform it into a map marker or map path entry.

  • the icon entry for my marker and any other variable entry I may need in my dataHandler transformFnc (i.e. “addSpaceStationPoint”)

This is how my config.js file looked after all the updates:

//Configuration file used by client side
var config = {
  http: {
    baseUrl: "https://marv.scriptrapps.io", //Your scriptr domain
    dataScript:"Maps/scripts/generateIssLiveData" //Scriptr script responsible for fetching needed geolocation data
  },
  websocket: {
    url: "wss://api.scriptrapps.io/RTg2MTczN0ZDRQ==",
    receive_channel: "ISSGeoLocation"//The Channel name to which the live GPS data will be pushed, and to which the client websocket will subscribe
  },
  map: {
    key: "AIzaSyBcPYghFh_BXz4dDz-TXTHbU2iV3Wbf57I", //https://developers.google.com/maps/documentation/javascript/get-api-key#get-an-api-key
    output: 'embed',
    type: "google.maps.MapTypeId.HYBRID", //MapTypeId.ROADMAP, MapTypeId.SATELLITE, MapTypeId.HYBRID, MapTypeId.TERRAIN 
    mode: ["marker", "polyline"], // flags to be used by the dataHandler transformFnc
    strokeColor: '#FF0000',
    strokeOpacity: 1.0, 
    strokeWeight: 1,
    zoom: 4,
    fetchCenter: true,
    defaultCenter: {lat: 32.7038888889, lng: -117.153611111},
    spaceStationIcon: 'https://icons.iconarchive.com/icons/aha-soft/free-global-security/32/Satellite-icon.png'
  },
  dataHandler: {
    transformFnc:  "addSpaceStationPoint" // //Define the transformation function you will use. ex: "renderEarthquakeGeoLocations", "renderRandomGeoLocations" 
  }
}

In the geolocation-mapping project, the data (i.e. geolocation of ISS) received as a message over the WebSocket is transformed into a map point by using one of the “Maps/static/dataHandler.js” functions.

Previously I defined “addSpaceStationPoint’  to be the name of my transformation function. I now must add its implementation to the “Maps/static/dataHandler.js” prototype.

addSpaceStationPoint: function(entries) {
           var config = this.args.config;
           if(!this.path) this.path = [];
           var markerData =  null;
           var pathData = null;
           for (var i = 0; i < entries.length; i++) {
              var entry = entries[i];
              markerData = {
                position: entry, //Longitute/Lattitude info of marker
                icon: config.spaceStationIcon,
              };
              
              if(config.mode.indexOf("polyline") != -1) {
              	 this.path.push(entry);
              }
              
              if(this.previousMarker) this.previousMarker.setMap(null);
              var marker = new google.maps.Marker(markerData);
              marker.setMap(map);
              this.previousMarker = marker;
              var routePath = new google.maps.Polyline({
                	path: this.path,
                	geodesic: true,
               	 	strokeColor:  window.config.map.strokeColor,
                	strokeOpacity: window.config.map.strokeOpacity,
                	strokeWeight: window.config.map.strokeWeight,
               	 	map: map
              	});
      	  }
      }

Finally, I need to change the “Maps/html/live.html” file and I will then be ready to track the International Space Station.

I will update all the includes fetched from a scriptr.io domain to point to my account:

<!–REPLACE marv.scriptrapps.io WITH YOUR SCRIPTR DOMAIN –> <script src=”https://marv.scriptrapps.io/Maps/static/config.js”></script> <script src=”https://marv.scriptrapps.io/Maps/static/wsClient.js”></script> <script src=”https://marv.scriptrapps.io/Maps/static/dataHandler.js”></script> <script src=”https://marv.scriptrapps.io/Maps/static/utils.js”></script>

As I can never be sure, where is the ISS right now, I will need to fetch explicitly for one time only its current location on the first load of the “Maps/html/live.html” page, using a direct http call to the api.

I will use the javascript scriptr httpClient available in the Geolocation Mapping module I imported.

  • I will include it as part of the scripts inside the live.html file head, and instantiate

<!–REPLACE marv.scriptrapps.io WITH YOUR SCRIPTR DOMAIN –> <script src=”https://marv.scriptrapps.io/Maps/static/httpClient.js”></script>

  • I will instantiate it in the $(window).load section
httpClient = new $.HTTPClient({config: window.config.http});

I will update the initMap function inside the live.html file, to issue an http request to the api, and on the success of the request I initialize the map with a center of  Lat & Lng values equal to the now location of the ISS.

function initMap() {
    httpClient.callApi(httpClient.buildRequest(), openSocketConnection, showFailMessage);
}

function openSocketConnection(entries) {
   var center = entries[0];
   map = new google.maps.Map(document.getElementById('map'), {
        zoom: (zoom !=null) ? parseInt(zoom) : window.config.map.zoom,
        center: center,
        mapTypeId: eval(window.config.map.type)
   });
   addMapPoints(entries);
   wsClient.openConnection(addMapPoints, showFailMessage);
 }

My work is now done. I can follow this link and voila! I can watch the ISS orbiting live.

Do you have any Live or Static Geolocation data you want to map? I look forward  to see you create awesome implementations like this!

In the meantime, we are hard at work adding new straightforward implementations to our easy to use scriptr.io, so please keep an eye out for updates at our GitHub account and our blog.