Protocol

All queries in this protocol are RESTful. By design, HTTP GET documents will not have side effects; they simply fetch documents. Only the HTTP POST methods accept data and updates.

All of these functions accept a callback param for the purposes of providing JSONP results..

These methods (mostly) require authentication tokens to function. You get all current tokens from your user page. You can get a write token from the auth_token URL. There's more details on this in the Authentication Types section below.

JSON — GET

/j — CurPos

This query returns the current position of the poster. In practical terms, this is simply the last fix entered into the database.

        {
          "found": true, // sometimes false, then no data

          "data": {
            "al":  "0",
            "l":   [42.83, -85.43],
            "t":   1297011751,
            "t_i": 1297011814,
            "tag": "test tag", // may be absent
            "poi": "test tag", // may be absent
            "vv":  ["94.66", "11.56"],

            "ha": "1", "va": "1"
          }

          // "error": "something bad happened"
        }
        

When found, the result of a CurPos query contains the following information. Of course, when nothing is found, there will be an error message.

CurPos takes exactly one (optional) parameter: token. When a token is provided, it allows others to see your current position for a limited time. For details on on the token parameter, see the below description of Token Authentication.

/f — FixDBQuery (fixes)

This default result is virtually the same as for CurPos, but with the addition of an array wrapper and a couple continuation fields. The query will not always return all the data in the database. When there is more data to get, it will be indicated by "more". The "offset" will indicate the start of the next data set and should be passed to the next query as is.

        {
          "found": true, // sometimes false, then no data

          "data": [
            { "al":, "l":, "t":, "t_i":, "poi":, "vv":, "ha":, "va": },
            { "al":, "l":, "t":, "t_i":, "poi":, "vv":, "ha":, "va": },
            { "al":, "l":, "t":, "t_i":, "poi":, "vv":, "ha":, "va": },
            { "al":, "l":, "t":, "t_i":, "poi":, "vv":, "ha":, "va": }
          ]

          "offset": 100, "more": true

          // "error": "something bad happened"
        }
        

For details on the data objects, please see CurPos as it is exactly the same. The parameters, on the other hand, are fairly complicated. Well, the token parameter works the same as in the CurPos query, and as before, the details can be found below under Token Authentication.

Here is an example FixDBQuery.

        function my_query(offset) {

        var searchParams = {
            p:  true, // always true for this type of query
            l:  350,
            tf: "readtime",
            o:  offset, // optional, unless continuing
            q:  escape("r=(1297011700,1297011752];ft=b"),
            d:  'asc'
        };

        // this is a jQuery invocation ($.getJSON() would also work here)
        $.ajax({ type: "GET", url: "/f", data: searchParams, dataType: 'json'
            error: function(xhr,et,ev){
                // normally this only happens when the server crashes somehow
                alert("internal error loading fixes: " + xhr.responseText.replace(/<[^>]+>/g, " "));
            },
            success: function(d){
                if( d.error ) {
                    // more typically, an error (if any) will be in the JSON result
                    alert("error loading fixes: " + d.error.replace(/<[^>]+>/g, " "));

                } else {
                    /* do things with the data */

                    if( d.more ) // go again if necessary
                        my_query(d.offset);
                }
            }
        });

        }

        

Beware, there is a difference between tf and ft. The difference of transposition is fairly invisible to the author without a second glance.

/f — FixDBQuery (stats)

        {
          "found": true, // sometimes false, then no data

          "data": {
              "1297554600": {"neat test": 2, "naked fixes": 2},
              "1297554000": {"neat test": 1},
              "1297554300": {"POI": 1, "neat test": 5, "naked fixes": 4}
          },

          "offset": 100, "more": true

          // "error": "something bad happened"
        }
        

The stats query results are very similar to the fix data result. The main difference is that instead of fixes, aggregate counts (by type) are returned. In the example above, there are two naked fixes and two fixes tagged "neat test" during the 1297554600 time period. (Each period is 300 seconds long;, unless, by off chance, spanning a leap second.)

        var searchParams = {
            p:  false, // always false for this type of query
            rm: false, // sometimes true, but then we POST

            /* params are otherwise the same as above */
        };

        var method = "GET";
        if( searchParams.rm )
            method = "POST";

        $.ajax({ type: method, url: "/f", data: searchParams, dataType: 'json'
            error: function(xhr,et,ev){ /* same as above */ },
            success: function(d){ /* same as above */ }
        });
        

The parameters for the status query are (by design) very much the same as for the fix data query. This allows the same search parameters to be used for both types of queries. So, for details on most of the params, go look above.

/t — TokenList

This JSON query does not take any options and simply returns the list of unexpired tokens. The "id" of the tokens are what you'd pass to the token modifying queries listed under HTML — POST. The types of the tokens are listed under Token Authenticated.

        [
          { "begin": 1297554731, "end": 1329954753,
            "token": "A!JfRUBdRxdUpiJBxcPkJy",
            "type_number": 3, "type": "post",
            "id": "aghqc29uLWdwc3IPCxIJQXV0aFRva2VuGAEM" }
        ]
        

/tt — TokenTest

You can quickly test a single token with this method. Give this method an url param of token and the result should be either true or false:

          { "result": true }
        

/g — UserGraphicsSettings

Aside from being a little crypitc, the user graphics table should be fairly self explainatory. The "a" param of the file data is the filepath to the given image (the _s suffix indicates “shadow”). Do not try to simply guess the filenames, as they are subject to change and will differ under token authentication. The "m" param is the meta data for the image. The image anchor (the part of the image that points to a thing on the map) is given under the "a" param — and counts in the positive direction from the upper left corner. And the "s" param is the size of the given image.

So, for example, the size of the curpos shadow is 56 pixels wide and 41 pixels tall. The anchor is set 7 from the left, and 37 from the top. There's no token in the file path, but there could be depending on the authentication mode of the query.

        { "curpos":   {"a": "/mi/curpos.png", "m": {"a": [6, 39], "s": [35, 41]}},
          "curpos_s": {"a": "/mi/curpos_s.png", "m": {"a": [7, 37], "s": [56, 41]}},
          "naked":    {"a": "/s/naked.png", "m": {"a": [10, 33], "s": [20, 34], "bi": true}},
          "naked_s":  {"a": "/s/shadow.png", "m": {"a": [2, 20], "s": [27, 20], "bi": true}},
          "tag":      {"a": "/s/tag.png", "m": {"a": [10, 33], "s": [20, 34], "bi": true}},
          "tag_s":    {"a": "/s/shadow.png", "m": {"a": [2, 20], "s": [27, 20], "bi": true}},
          "poi":      {"a": "/s/poi.png", "m": {"a": [10, 33], "s": [20, 34], "bi": true}},
          "poi_s":    {"a": "/s/shadow.png", "m": {"a": [2, 20], "s": [27, 20], "bi": true}}},
          "both":     {"a": "/s/both.png", "m": {"a": [10, 33], "s": [20, 34], "bi": true}},
          "both_s":   {"a": "/s/shadow.png", "m": {"a": [2, 20], "s": [27, 20], "bi": true}}
        }
        

/mi — MyImage

This is only included for completeness. It doesn't take any traditional CGI parameters, only the token in the URL. The URL will be precomputed and included in the output of UserGraphicsSettings.

JSON — POST

/input — Input

This input method takes JSON data directly in a param named fixes. Every modern language should have a nice JSON coder, probably more than one. The example below is using Prototype.js Object.toJSON and Ajax.

The params in each fix objects are all very much the same as enumerated in the curpos result section above. Well, there are a couple exceptions. t_i is internally calculated — so that shall not be provided. Also, span t can optionally be an array of times (useful data compression for fixes from a stationary data source).

This method also requires an authentication token. For full details on this, see the Token Authentication section below.


        var fixes = $A([]); // a Prototype.js array object

        fixes.push({
         // if t: is more than 11 digits, it's assumed to be
         // milliseconds rather than seconds since the epoch
         t: 1297554052,
         l: ["42.3270","-85.5651""]
         al: 1,
         va: 1, ha: 1,
         poi: "woah, this is interesting", // optional
         tag: "grocery trip", // optional
         vv: [0.0,90.0]
        });

        fixes.push({ t:[1,2,3,4] /* more data */});

        fixes.push({/* more data */});
        fixes.push({/* more data */});

        var request = new Ajax.Request('http://db.JGPS.me/input', {
            method: 'post',

            parameters: { // send_view_url: true,
                fixes: fixes.toJSON(),
                token: authenticationToken
            },

            onSuccess: function(transport) {
                var rt = transport.responseText.evalJSON().fix_tlist;

                if( rt ) {
                    for(var i=0; i<rt.length; i++) {
                        var t = rt[i]; // timestamp of the posted fix

                        rmFromOutboundQueue(t);
                    }
                }
            }
        });
        

Posted fixes are acknowledged via their timestamp. The response should present a a timestamp for each fix posted to the database (the timestamp should exactly match the timestamp given) Responses can also have other items though.

        {
            "fix_tlist": [1297554052],

            "meta": {
                "view_url": 'http://jgps.me/l/tokentokentoken'
             // "auth_url": 'http://jgps.me/auth_token'
            }

            // "error": "message here, iff applicable, normally not"
        }
        

HTML — POST

The results of these queries don't really matter. They either work or they don't. You needn't really look any further than the HTTP status code that comes back. Although, each takes a return param such that an HTML redirect will be shown to a client (if desired).

        $.ajax({ type: "POST",
            url: "/rm_t", // or mk_t or up_t
            data: {
            // where you'd like to go after the HTTP 200
                r: 'http://google.com',
            /* other required data */ },
        });
        

/rm_t — RmToken

To remove or revoke a token, simply specify its id.

            $.ajax({ type: "POST", "/rm_t",
                data: {k: id},
                success: function(){ /* worked */ },
                error: function(){ /* failed */ }
            });
        

/mk_t — AddToken

To create a new token, specify a type and the beginning and ending of the token's valid life. See Token Authentication for a list of valid token types and additional parameters.

            $.ajax({ type: "POST", "/mk_t",
                data: {
                    t: 'curpos',
                    b: 1297011751,
                    e: 1297014751

                    /* search gets: tf,q,l,d */
                },
                success: function(){ /* worked */ },
                error: function(){ /* failed */ }
            });
        

/up_t — UpdateToken

To update the expiration (and begin time) for a given token, specify the token key and the begin and end times you'd like.

            $.ajax({ type: "POST", "/up_t",
                data: {
                    k: id,
                    b: 1297011751,
                    e: 1297014751
                },
                success: function(){ /* worked */ },
                error: function(){ /* failed */ }
            });
        

Authentication Types

You get all current tokens from your user page. You can get a write token from the auth_token URL.

Token Authenticated

There are various different types of tokens in this system. They all point to your user information in some way, ways that you can specify and revoke at will. Tokens have expirations, so you don't have to pay close attention to them.

Tokens also have a beginning such that with careful planning, tokens can come alive at appointed times and go away again when you're done (e.g., during a meeting?).

Tokens are removed from the system when they expire.

Most tokens authorize only limited access to data you specify, though all give access to your user graphics settings (aka map pins). All tokens have a key string, a beginning time and an end time. Some tokens may have additional parameters. The valid token types, and their parameters, are as follows.

  1. "curpos": your current location.
  2. "auto_curpos": this is the same as the above, but is generated and updated internally when receiving new input data.
  3. "search": rather like the above but also takes search parameters. The parameters are stored with the token, such that maps authenticated with these tokens will only show the data enumerated under the token.
  4. "post": tokens of this type may post fixes as the parent user

Auth URL

Some devices keep a security wall between browser widgets and application space. For this reason, by default, the auth_url is an html form that presents the token to the user for cut and paste. This behavior can be overridden by adding a j=1 URL param to the auth_url — making it return JSON/JSONP instead. Note that this will not differ overmuch from the TokenList above.

User Authenticated

When you log in as a standard user, this is what we call user authenticated. It's your login. it's pretty boring!