Journey Recording using GPS Tracking
Hi Joe,
There are 2 modes of Geolocation: monitoring accurate data from the satellite (function watchPosition) and less accurate data (IP location or wifi) (function getCurrentPosition).
By default, getCurrentPosition () tries to answer as fast as possible with a low accuracy result. It is usefull if you need a quick answer regardless of the accuracy. Devices with a GPS, for example, can take a minute or more to get a GPS fix, so less accurate data (IP location or WiFi) may be returned to getCurrentPosition ().
watchPosition () produces more accurate data, but you can not control when it's received. (Eg data may be received after the turn and part of the journey will be cut off).
Besides using watchPosition function successCallback invokes only if new position differs significantly from the previous position - because of this if you drive slowly and when standing still - successCallback function is invoked rarely (once per minute or less), and update is rare.
That's why accurate (up to one meter) measuring the distance and speed is impossible. Distance will be obtained only approximately (+ - a few percent).
Here's a little guide how to try this. Distance is obtained by means of function watchPosition. When satellite signals are installed (this can take a few minutes) - the motion data will be updated every 3-4 seconds. Distance will be measured quite accurately. After pressing the init Geolocation service runs for communications with the satellite. After clicking on the start button gathering data starts. When you press the pause data collection is suspended (for example, during a stop).
1) Add Geolocation service to your app
2) On page where you want to record speed add Geolocation service named geolocation1 with the following Request parameters:
maximumAge = 3000
timeout = 5000
enableHighAccuracy = true
watchPosition = checked
3) Create new JS asset with the following code:
codevar running = false, paused = true, oldLat = 0, oldLng = 0, oldTime = 0, totalTime = 0, totalDist = 0, invokeTimes = 0, map, marker;
function findDistance(t1, n1, t2, n2) {
var lat1, lon1, lat2, lon2, dlat, dlon, a, c, dk, mi, km, Rk = 6371 ;
Code: Select all
// convert coordinates to radians
lat1 = deg2rad(t1);
lon1 = deg2rad(n1);
lat2 = deg2rad(t2);
lon2 = deg2rad(n2);
// find the differences between the coordinates
dlat = lat2 - lat1;
dlon = lon2 - lon1;
// here's the heavy lifting
a = Math.pow(Math.sin(dlat/2),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2),2);
c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a)); // great circle distance in radians
dk = c * Rk; // great circle distance in km
// round the result down to the nearest 1/1000
km = round(dk);
return km; }
// convert degrees to radians
function deg2rad(deg) {
rad = deg * Math.PI/180; // radians = degrees * pi/180
return rad;
}
// round to the nearest 1/1000
function round(x) {
return Math.round( x * 1000) / 1000;
}
//convert Milliseconds to Time string
function mSecToTime(mSec){
var time = Math.floor(mSec/1000);
var hours = Math.floor(time / 3600);
time = time - hours * 3600;
var minutes = Math.floor(time / 60);
var seconds = time - minutes * 60;
return hours + ':' + minutes+ ':' + seconds;
}
function updateMarker (lat, lng){
if (!map) {
map = Tiggzi("map").gmap;
}
var newPoint = new google.maps.LatLng(lat, lng);
if (marker) {
// Marker already created - Move it
marker.setPosition(newPoint);
} else {
// Marker does not exist - Create it
marker = new google.maps.Marker({
position: newPoint,
map: map
});
}
// Center the map on the new position
map.setCenter(newPoint);
}/code
4) Add on page:
map named map
5 labels with names: errorLabel, totalDistLabel, totalTimeLabel, avrSpeedLabel, dataLabel
3 buttons named: init, start, pause
5) on Page show run:
codeAppery("pause").hide();
Appery("start").hide();/code
6) on init-Click run:
codeAppery("init").hide();
Appery("start").show();
if (!running) {
running = true;
geolocation1.execute({});
}/code
7) on pause-Click run:
codepaused = true;
Appery("pause").hide();
Appery("start").show();
oldTime = 0;
oldLat = 0;
oldLng = 0;/code
8) on start-Click run:
codepaused = false;
Appery("pause").show();
Appery("start").hide();/code
9) on geolocation1-Success run:
codeAppery("errorLabel").hide();
invokeTimes++;
Appery("dataLabel").html('Latitude: ' + data.coords.latitude + '<br>' +
'Longitude: ' + data.coords.longitude + '<br>' +
'Altitude: ' + data.coords.altitude + '<br>' +
'Accuracy: ' + data.coords.accuracy + '<br>' +
'Timestamp: ' + data.timestamp + '<br>');
if(!paused) {
if(oldTime != 0) {
var dist = findDistance(oldLat, oldLng, data.coords.latitude, data.coords.longitude);
totalDist += dist;
totalTime += data.timestamp - oldTime;
}
oldTime = data.timestamp;
oldLat = data.coords.latitude;
oldLng = data.coords.longitude;
Appery("totalDistLabel").text("Distance: " + round(totalDist) + ' km');
Appery("totalTimeLabel").text("Time: " + mSecToTime(totalTime));
if (totalTime>0) {
Appery("avrSpeedLabel").text("Average speed: " + round(totalDist/(totalTime/(1000*3600))) + " km/h");
} else {
Appery("avrSpeedLabel").text("Average speed: 0 km/h");
}
}
updateMarker(data.coords.latitude, data.coords.longitude);/code
10) on geolocation1-Fail run:
codevar date = new Date();
date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()
Appery("errorLabel").text("Some error occured at " + (date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()));
Appery("errorLabel").show();/codePlease try adding this on the NEW app, not yours. Because it can conflict with the old one (for example, because of the same names of variables or functions). If it works correctly then try it in your app.