You are here :

 Upload Track API

Sunday, 6. September 2009 17:34:27, by Manolis Andreadakis

 

You can use this API to send a track recored with LeonardoLive compatible programs to a LeonardoXC server.

There are 2 options:

  1. Send the track that is stored at the server, so no re-uploading is done, but this means that the tracking interval be may too big or that there are missing trackpoints due to bad mobile signal. This method is reffered to as 'live-partial-submit'
  1. Re-upload the trackpoints that the program has stored internally into the phone, it may be even at 1 sec interval! This is the recommended method and it is called 'full-reupload'. This method uses a) differential format so that only changes between points are written AND b) a 'deflate' compression on the resulting output. This makes a very efficient compression of rates up to 90%

A tracklog of 2 sec interval and duration of 1 hour consists of 1800 trackpoints, it will convert in differential format at 7200 bytes and deflated around 55% will result in 3960 bytes or 3,8 Kb

URL to POST

www.livetrack24.com/client.php

or for testing

test.livetrack24.com/client.php

NOTE : the test url is for submitting tracks recorded on the test server by using the 'live-partial-submit' option.

POST VARIABLES

Variables needed in all methods

Variable name     Values
op             => submit  

sessionID      => The sessionID of the tracklog
liveUsername   => The username of on livetrack24.com
liveUserID     => The userID IF the user has loggedin, else use 0
gliderType     => put the NUMERIC value from the table below
   1=>"Paraglider"
   2=>"Flex wing FAI1"
   4=>"Rigid wing FAI5"
   8=>"Glider"
   16=>"Paramotor"
   32=>"Trike"
   64=>"Powered flight"
   128=>"Hot Air Balloon"
   16385=>"Walk"
   16386=>"Run"
   16388=>"Bike"

gliderName     => Name of the vehicle/glider ie "Gradient Golden 2 26"
platform       => Nokia 2600c // the phone model as it is acquired from a system  call
gps            => the GPS name , use the string "Internal GPS" for phones with integrated GPS
programName    => fixed value use only alphanumerics no spaces, first Letter of words in capitals
programVersion => version of your program you can use free text like 1.4.5
comments       => user provided comments aboub the flight
url            => a user provided URL that may contain further info about the flight

leonardoServer => the numeric ID of the target leonardo server, here is the list up today
   1=>www.paraglidingforum.com
   2=>www.sky.gr    
   3=>www.xcportugal.com
   4=>www.xcbrasil.org
   5=>xc.DHV.de
   7=>www.foroparapente.co
 so for example use 1 for sending to paraglidingforum.com

username       => leonardoXC username
password       => leonardoXC password

Variables for 'live-partial-submit'
format         => ALREADY_UPLOADED_DATA

Variables for 'full-reupload'
format         => FORMAT_BINARY_COMPRESSED
compressed     => 1 for 'deflated' , 0 for just the differential format
trackID        => If the track was live and the program had a means to
                  grab the trackID of on the server then give it here. Or just put 0, 
firstTM        => the Timestamp (sec till unix epoch 1-1-1970 GMT) of the first point.

Prepare the compressed file

INIT VARIABLES
 tm0=0;
 latitude0=0;
 longitude0=0;
 alt0=0;

FOR EACH TRACKPOINT DO
  if (tm0==0) {
     // we output the full record , this is the first TRACKPOINT
     CALL fullRecordBinary() 
  } else {
       // see if we can use differential format:
       /* 
       1        Full or diff format        
       3        time diff        8 secs
       7        alt diff        6 bits-> 64 m + 1 bit sign
       11        lat diff        10 bits + 1 sign (1024)
       10        lon diff         9 bits + 1 sign (512)
       total 1+3+7+11+10 = 32 bits = 4 bytes
       */
       int d_tm=tm-tm0;
       int d_alt=alt-alt0;
       int d_lat=latitude-latitude0;
       int d_lon=longitude - longitude0;
       if ( d_tm < 8 && Math.abs(d_alt) < 64 && 
                       Math.abs(d_lat) < 1024 && Math.abs(d_lon) < 512 ) {
               
               byte# outBytes =new byte4;
               
               // 12345678 12345678 12345678 12345678
               // FtttAaaa aaaOoooo oooooLll llllllll
               
               outBytes0=outBytes1=outBytes2=outBytes3=0;
               
               outBytes0= (byte)0x80; // differential format
               outBytes0 |=  (byte)( (d_tm << 4) & 0x70 ) ;
               if (d_alt<0) outBytes0 |= 0x08; // negative d_alt
               outBytes0 |=  (byte)( (Math.abs(d_alt) >>3 ) & 0x07 ) ;
               
               
               outBytes1 |=  (byte)( (Math.abs(d_alt) <<5 ) & 0xE0 ) ;
               if (d_lon<0) outBytes1 |= 0x10; // negative d_lon
               outBytes1 |=  (byte)( (Math.abs(d_lon) >> 5) & 0x0F ) ;
               
               outBytes2 |=  (byte)( (Math.abs(d_lon) << 3) & 0xF8 ) ;
               if (d_lat<0) outBytes2 |= 0x04; // negative d_lat
               outBytes2 |=  (byte)( (Math.abs(d_lat) >> 8) & 0x03 ) ;
               
               outBytes3 |=  (byte)( (Math.abs(d_lat) ) & 0xFF ) ;

               out.write(outBytes);
       } else { // revert to full
         // we output the full record
         CALL fullRecordBinary() 
       }
       
 }

 tm0=tm;
 latitude0=latitude;
 longitude0=longitude;
 alt0=alt;

GO ON WITH THE NEXT TRACKPOINT...

FullRecord2Binary()

       final static private int DEGREESTOINT = 46603;

       public static byte# fullRecordBinary(int tm,Float lon,Float lat,short alt) {

                res_arr20=toByta(tm);
                
                res_arr21=new byte3;
                res_arr22=new byte3;
                
                int longitude = lon *         DEGREESTOINT ;
                res_arr210 = (byte)(0xff & (longitude >> 16));
                res_arr211 = (byte)(0xff & (longitude >> 8));
                res_arr212 = (byte)(0xff & longitude);

               int latitude = lat *  DEGREESTOINT
                res_arr220 = (byte)(0xff & (latitude >> 16));
                res_arr221 = (byte)(0xff & (latitude >> 8));
                res_arr222 = (byte)(0xff & latitude);
                 
               
                res_arr23=toByta(alt);        
                
                byte# res=concat(res_arr2);
                return res;                 
       }

       public static byte# toByta(int data) {
           return new byte# {
               (byte)((data >> 24) & 0xff),
               (byte)((data >> 16) & 0xff),
               (byte)((data >> 8) & 0xff),
               (byte)((data >> 0) & 0xff),
           };
       }


       public static byte# toByta(short data) {
           return new byte# {
               (byte)((data >> 8) & 0xff),
               (byte)((data >> 0) & 0xff),
           };
       }