This documentation shows how to create a map that is updated at each new coordinates it receives. In this documentation, coordinates are sent via inject nodes but for a real case replace them by a mqtt node, for example.

OwnTracks

In this example, we’ll use an owntracks node, if you don’t know how to configure it on your mobile phone in order to use it, go to the “Make some actions depending on the distance between two GPS positions” example first. You can go by clicking Here.

It is necessary to insert an owntracks node:

Next, configure the owntracks node like in the picture, by replacing the value by the one you configured on you mobile device.

Then, in the second tab, you have to indicate on witch MQTT server you want to connect(it have to match with the one you chosen while you configured you mobile device connection):

This node will send the coordinates you want to display on the map each time your device will send a location report.

The send position will be interpreted like an itinerary.

Http

After, create a webpage to display the map. For this, drop-and-drag one http in and one http out node:

Since the node http out does not need configuration simply set the node http in like that :

Template

Then, take a template node to display the map on the webpage:

The template node contain a code to display the map and marker that indicate a position.

<!DOCTYPE html>
<html>
<head>
<title>Owntracks & The ThingBox Live Map</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" src="http://yourjavascript.com/4594301102/gmaps.js"></script>

<style type="text/css" media="screen">
    #map {
    position:absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    }
</style>
</head>
<body>

<div id="map"></div>
<script type="text/javascript">
var socketaddy = "ws://thethingbox:1880/api/ws/location";
    var map;
    var sock;
    $(document).ready(function(){

    map = new GMaps({
       div: '#map',
       lat: -12.043333,
       lng: -77.028333
    });


    sock = new WebSocket(socketaddy);
    sock.onopen = function(){ console.log("Connected websocket");
       console.log("Sending ping..");
       sock.send("Ping!");
       console.log("Ping sent..");
    };
    sock.onerror = function(){ console.log("Websocket error"); };
    sock.onmessage = function(evt){
       var latlng = JSON.parse(evt.data);
       var array = $.map(latlng, function(el) {
         return [[el.lat, el.lng]];
         });

       map.removeMarkers();
       map.removePolylines();
       console.log("Got marker at " + latlng[0].lat + ", " + latlng[0].lng, latlng);
       map.setZoom(17);
       map.setCenter(latlng[0].lat, latlng[0].lng);
       map.addMarkers(latlng);
       map.drawPolyline({
       path: array,
       strokeColor: '#131540',
       strokeOpacity: 0.6,
       strokeWeight: 6
       });
    }
    });
</script>
</body>
</html>

Pay attention to replace the address in this line:

var socketaddy = "ws://thethingbox:1880/api/ws/location";

By this one (thethingbox must be replaced by you box IP):

var socketaddy = "ws://YOUR_BOX_IP:1880/api/ws/location";

It is possible to change the settings of different options like colour, opacity and weight of the route line or the zoom and the centre of the map.

Functions

Afterwards, insert three function nodes that will send the coordinates to web socket:

The code in the function 1 is to store the coordinates into a global variable:

context.global.location=msg.payload;
return msg;

In the function 2 the code is to load the coordinates into the map:

msg.payload=context.global.location;
return msg;

To finish, the last function will adapt datas between those sent and those that the map uses. To do this, it must replace latitude and longitude by lat and lng, and put it in this form.

var latitude = msg.payload.latitude;
var longitude = msg.payload.longitude;
msg.payload = '[{"lat":"' + latitude + '","lng":"' + longitude + '"}]';
return msg;

Websocket

Finally, to update the map add two web socket node, one in and one out:

These nodes will update the map with the coordinates they receive. Moreover they have the same configuration:

To finish, link these nodes like that:

There is here the code to import in node-red to insert the flow in the sheet:

[{"id":"e3fec925.2c1cb","type":"websocket-listener","path":"/ws/location","wholemsg":"false"},{"id":"6189e5cf.9e761c","type":"owntracks","name":"","broker":"test.mosquitto.org","port":1883,"clientid":"","topic":"thethingbox/position/nickname","x":479,"y":4396,"z":"c3aed0d3.3ce58","wires":[["6d974bf4.9268b4"]]},{"id":"11b7317e.ee48cf","type":"websocket out","name":"","server":"e3fec925.2c1cb","x":1084,"y":4440,"z":"c3aed0d3.3ce58","wires":[]},{"id":"e017661c.1fe898","type":"websocket in","name":"","server":"e3fec925.2c1cb","x":648,"y":4492,"z":"c3aed0d3.3ce58","wires":[["969ca591.696358"]]},{"id":"356da181.ca925e","type":"http in","name":"","url":"/map","method":"get","x":537,"y":4562,"z":"c3aed0d3.3ce58","wires":[["db27c64b.24d838"]]},{"id":"a5f22b9d.5a0dd8","type":"http response","name":"","x":985,"y":4562,"z":"c3aed0d3.3ce58","wires":[]},{"id":"db27c64b.24d838","type":"template","name":"","template":"<!DOCTYPE html>\n<html>\n<head>\n  <title>Owntracks & The ThingBox Live Map</title>\n  <script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js\"></script>\n  <script type=\"text/javascript\" src=\"http://maps.google.com/maps/api/js?sensor=true\"></script>\n  <script type=\"text/javascript\" src=\"http://yourjavascript.com/4594301102/gmaps.js\"></script>\n \n  <style type=\"text/css\" media=\"screen\">\n    #map {\n      position:absolute;\n      top: 0; bottom: 0; left: 0; right: 0;\n    }\n  </style>\n</head>\n<body>\n \n  <div id=\"map\"></div>\n  <script type=\"text/javascript\">\n  var socketaddy = \"ws://thethingbox:1880/api/ws/location\";\n    var map;\n    var sock;\n    $(document).ready(function(){\n      \n      map = new GMaps({\n        div: '#map',\n        lat: -12.043333,\n        lng: -77.028333\n      });\n      \n      \n      sock = new WebSocket(socketaddy);\n      sock.onopen = function(){ console.log(\"Connected websocket\");\n\t      console.log(\"Sending ping..\");\n\t      sock.send(\"Ping!\");\n\t      console.log(\"Ping sent..\");\n      };\n      sock.onerror = function(){ console.log(\"Websocket error\"); };\n      sock.onmessage = function(evt){\n        var latlng = JSON.parse(evt.data);\n        var array = $.map(latlng, function(el) {\n  \t\t\treturn [[el.lat, el.lng]];\n\t\t\t});\n        \n        map.removeMarkers();\n        map.removePolylines();\n       \tconsole.log(\"Got marker at \" + latlng[0].lat + \", \" + latlng[0].lng, latlng);\n        map.setZoom(17);\n       \tmap.setCenter(latlng[0].lat, latlng[0].lng);\n        map.addMarkers(latlng);\n      \tmap.drawPolyline({\n\t\t  path: array,\n\t\t  strokeColor: '#131540',\n\t\t  strokeOpacity: 0.6,\n\t\t  strokeWeight: 6\n\t\t});\n      }\n    });\n  </script>\n</body>\n</html>","x":757,"y":4562,"z":"c3aed0d3.3ce58","wires":[["a5f22b9d.5a0dd8"]]},{"id":"969ca591.696358","type":"function","name":"function 2","func":"// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n//   console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n//   context = {};\n\nmsg.payload = context.global.location;\n\nreturn msg;","outputs":1,"x":874,"y":4492,"z":"c3aed0d3.3ce58","wires":[["11b7317e.ee48cf"]]},{"id":"f4b26854.0b4d98","type":"function","name":"function 1","func":"// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n//   console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n//   context = {};\ncontext.global.location = msg.payload;\n\nreturn msg;","outputs":1,"x":877,"y":4396,"z":"c3aed0d3.3ce58","wires":[["11b7317e.ee48cf"]]},{"id":"6d974bf4.9268b4","type":"function","name":"Adaptation","func":"var latitude = msg.payload.latitude;\nvar longitude = msg.payload.longitude;\nmsg.payload = '[{\"lat\":\"' + latitude + '\",\"lng\":\"' + longitude + '\"}]'; \nreturn msg;","outputs":1,"x":719,"y":4396,"z":"c3aed0d3.3ce58","wires":[["f4b26854.0b4d98"]]}]

How to see the map?

Now the flow display the map at the address thethingbox:1880/api/map (replace thethingbox by your box name or IP address).

After deploying the flow, go at the address above:

Next, once coordinates are sent by clicking on the inject button the map will be automatically updated and indicate the position thanks to a marker:

sources: http://flows.nodered.org/flow/1aab1d44e387da96b3fe

Back to top