Animate real-time path with live streaming data

Hello,

my goal is to animate real time drone’s path with live stream data (data send every 2s, API REST, to get JSON packet). For now i just able to make points every X seconds on the map (like chain) when i reach coordinates from API request and that point not even have altitude (somehow using only longitude and latitude).

I tried to search examples, but most of them are using completed long CZML file with all coordantes and just simply using load function. I know that each telemetry update can be turned into a CZML packet containing the time and the new sample value for properties like position or orientation. And in that situation need using function process instead load (also cant understand how to use properly). I misunderstand so many small but important things like:

  1. Do i need append every new packet to old one or its fine to load every CZML file as new one
  2. How to make my drone drag several seconds that i could get coordinates from API request and then drone can move smoothly from one point to another (use Callback function, ExtrapolationType.HOLD?). I know some things, but i am not able to combine into one code.
  3. why in Sandcastle $AJAX not working

Essentially i just need some example, which shows where i need to put my live streaming gps coordinates every X seconds from my API request and how to get smoothly moving path from one point to another. Like this: Time-tagged properties for a 3D model

Any suggestion or recommendations are appreciated

I know that my code is garbage, but maybe there will be possible to add something to change situation:

var viewer = new Cesium.Viewer("cesiumContainer");

const api_url = 'https://api.wheretheiss.at/v1/satellites/25544';
const data_type =  'json';
const request_type = 'GET';
let lon;
let lat;
let height;
let czmlnow;

function getData(){
  $.ajax({
    async: false,
    type: request_type,
    url: api_url,
    datatype: data_type,
    success: function(data){
      lon = data.longitude;
      lat = data.latitude;
      height = data.altitude;
    }  
  });


czmlnow = [
{
"id" : "document",
"name" : "CZML Point - Time Dynamic",
"version" : "1.0"
}, 
{
"id" : "point",
//"availability" : "2012-08-04T16:00:00Z/2012-08-04T16:05:00Z",
"position" : {
  "epoch" : "2012-08-04T16:00:00Z",
  "cartographicDegrees" : [lon,lat,height]
},
"point" : {
  "color" : {
  "rgba" : [255, 255, 255, 128]
  },
"outlineColor" : {
  "rgba" : [255, 0, 0, 128]
  },
"outlineWidth" : 2,
"pixelSize" : 10
  }

}
];
  var dataSourcePromise = Cesium.CzmlDataSource.load(czmlnow); //process not working
  viewer.dataSources.add(dataSourcePromise);
  //console.log(lat,lon,height)
      }


setInterval(getData, 1000);

Update: im trying update czml file every x seconds and put in process(czml), but it doesn’t work,entity shows for one loop and disappears. This code is for update cheking purpose (creat czml packet with coordinates array and trying send it again after X seconds)

  const api_url = 'https://api.wheretheiss.at/v1/satellites/25544';
  const data_type =  'json';
  const request_type = 'GET';
  let lon;
  let lat;
  let height;
  let arr=[];
  
  function get_data(){
   for (let i=0; i < 10; i++){
  
      $.ajax({
        async: false,
        type: request_type,
        url: api_url,
        datatype: data_type,
        success: function(data){
          lon = data.longitude;
          lat = data.latitude;
          height = data.altitude;
          if (typeof data !== 'undefined'){arr.push(i,lon+i,lat,height*1000) };
          console.log(arr)
        }  
      })
  
  var czml = [
    {
      id: "document",
      name: "CZML Path",
      version: "1.0",
      clock: {
        interval: "2012-08-04T10:00:00Z/2012-08-04T15:00:00Z",
        currentTime: "2012-08-04T10:00:00Z",
        multiplier: 1,
      },
    },
    {
      id: "path",
      name: "path with GPS flight data",
      description:
        "<p>Hang gliding flight log data from Daniel H. Friedman.<br>Icon created by Larisa Skosyrska from the Noun Project</p>",
      availability: "2012-08-04T10:00:00Z/2012-08-04T15:00:00Z",
      path: {
        material: {
          polylineOutline: {
            color: {
              rgba: [255, 0, 255, 255],
            },
            outlineColor: {
              rgba: [0, 255, 255, 255],
            },
            outlineWidth: 5,
          },
        },
        width: 8,
        leadTime: 0,
        trailTime: 1000,
        resolution: 5,
      },
      billboard: {
        image: 'image'
        scale: 1.5,
        eyeOffset: {
          cartesian: [0.0, 0.0, -10.0],
        },
      },
      position: {
        epoch: "2012-08-04T10:00:00Z",
         cartographicDegrees : arr 
      },
    },
  ];
  
  }
  return czml;
  }
  
  //setInterval(get_data,10000);
  //setInterval(source,10000);
  
  function source(){
    return  new Cesium.CzmlDataSource();
  }
  
  
  
  var viewer = new Cesium.Viewer("cesiumContainer", {
    terrainProvider: Cesium.createWorldTerrain(),
    baseLayerPicker: false,
    shouldAnimate: true,
    
  });
  
  viewer.dataSources
    .add(source().process(get_data()))
    .then(function (ds) {
      viewer.trackedEntity = ds.entities.getById("path");
    });
1 Like

in example above I think it use pre loaded data, but you want live stream

so if a packet come I interpolate between two point, for example divide 20 equal part of between two point and you get a bigger resolution linestring.

after that I draw 20 line from this array every (2 * 1000 ) / 20 = 100ms
may be I can use primitive collection for this,

after draw this packet as 20 line(primitive), I destroy 20 line and I draw as a single line (for reduce ptimitive object count) because it complete.

so after that I can draw same way new packet and after that I turn to single line again,

may be I can turn this lines to bigger single line, optimization is up to you.

3 Likes