Skip to content

Instantly share code, notes, and snippets.

@JamesTheAwesomeDude
Created August 5, 2020 19:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamesTheAwesomeDude/22b4557cc4f7130ec6e8e0842fcb4121 to your computer and use it in GitHub Desktop.
Save JamesTheAwesomeDude/22b4557cc4f7130ec6e8e0842fcb4121 to your computer and use it in GitHub Desktop.
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GPS Trace 0.3</title>
<script src="http://www.ishygddt.xyz/~james/openlocationcode.min.js"></script>
<script src="http://www.ishygddt.xyz/~james/distVincenty.js"></script>
<script>
const softwareVersionString="My Apologies 20200805 - https://www.github.com/JamesTheAwesomeDude"
var tripLog=new Object();
function _main(){
initializeTripLog();
geo.watchPosition(pos=>{
//openTripLogSegment(tripLog);
updateUserDisplays(pos);
updateTripLog(tripLog,pos);
},
err=>{
invalidateUserDisplays();
//closeTripLogSegment(tripLog);
offerToSaveTripLog(tripLog);
}
);
}
function main(event){//body.onload=='main(event);'
_main();
}
const geo=navigator.geolocation;
const unitConversion={
'm/s': 1,
'mph': 2.23693629205440229,
'm': 1,
'km': 0.001,
'miles': 6.213711922373339e-4
}
function updateUserDisplays(pos){
let lat=pos.coords.latitude;
let lon=pos.coords.longitude;
let speed=pos.coords.speed;
let heading=pos.coords.heading;
//let course=getCourse(tripLog,pos);
let accuracy=pos.coords.accuracy;
let ele=pos.coords.altitude;
let eleAccuracy=pos.coords.altitudeAccuracy;
let speedEl=document.getElementById('speed');
let locationEl=document.getElementById('location');
let distanceEl=document.getElementById('distance');
speedEl.textContent=renderPrettySpeed(pos.coords.speed);// + renderPrettyBearing(tripLog,pos)
locationEl.textContent=renderPrettyCoords(lat,lon);
distanceEl=renderPrettyDistance(tripLog,pos);
}
function renderPrettySpeed(speed,unit='mph'){
if(isNaN(speed)) return '???';
return (speed*unitConversions[unit]).toFixed(1)+unit;
}
function renderPrettyCoords(lat,long){
return OpenLocationCode.encode(lat,long,OpenLocationCode.CODE_PRECISION_EXTRA).slice(4);
}
function renderPrettyDistance(tripLog,pos){
return '[TODO]';
}
function initializeTripLog(){
tripLog.date=new Date();
tripLog.entries=[];
tripLog.footer=`</gpx>`
}
function updateTripLog(tripLog,pos){
tripLog.entries.push(pos);
}
function offerToSaveTripLog(tripLog){
let payload=[];
tripLogVibeCheck(tripLog);
payload.push(
`<?xml version="1.0"?>
<gpx
version="1.0"
creator="${softwareVersionString}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0
http://www.topografix.com/GPX/1/0/gpx.xsd">
<time>${tripLog.date.toISOString()}</time>
`
);
payload.push(
`<trk><name>${escapeText(prompt('What do you want to name this trace?') || 'test run')}</name>
<trkseg>
` //TODO: multi-segments based on when the page lost focus
);
tripLog.entries.forEach(pos=>{
let lat=pos.coords.latitude;
let lon=pos.coords.longitude;
let ele=pos.coords.altitude;
let time=(d=new Date(pos.timestamp)).toISOString();
payload.push(
`<trkpt lat="${lat}" lon="${lon}">${
ele?` <ele>${ele}</ele>
`:''}
<time>${time}</time>
</trkpt>
`
);
});
payload.push(
`</trkseg>
</trk>
`
);
payload.push(
`</gpx>`
);
let container=document.getElementById('tripLogLinkWrapper');
let a=document.createElement('a');
let fname=`trip_${getYYYYMMDDHHMM()}.gpx`;
a.href=renderBlobURL(payload,fname,{type:'text/xml'});
a.download=fname;
a.textContent=fname;
a.onclick=ev=>setTimeout(e=>{
URL.revokeObjectURL(
e.parentNode.removeChild(e)
.href
);
},0,ev.target);
container.appendChild(a);
}
function getYYYYMMDDHHMM(d=new Date()){
const pad=s=>('0'+s).slice(('0'+s).length-2);
return `${d.getFullYear()}${pad(d.getMonth()+1)}${pad(d.getDate())}${pad(d.getHours())}${pad(d.getMinutes())}`;
}
function escapeText(s){
let e=document.createElement('p');
e.textContent=s;
return e.innerHTML;
}
function renderBlobURL(data,fname,properties){// ht- https://stackoverflow.com/a/32295448/1874170
let file;
try {
file = new File(data, fname, properties);
} catch(e) {
file = new Blob(data, properties);
}
return URL.createObjectURL(file);
}
function tripLogVibeCheck(tripLog){
let numberOfZeroEles=tripLog.entries.reduce(
(n,pos)=>(
n+(pos.coords.altitude==0.0)
),
0
);
if(numberOfZeroEles>Math.sqrt(tripLog.entries.length)){
tripLog.entries.forEach(pos=>{
delete pos.coords.altitude;
});
}
}
</script>
<style>
.telemetryDisplayWrapper {
text-align: center;
}
#speed {
font-size: xx-large;
font-weight: bold;
}
#location {
font-size: x-large;
}
#distance {
font-size: large;
}
</style>
</head>
<body onload="main();">
<div class="telemetryDisplayWrapper">
<p id="speedWrapper">Speed: <span id="speed">…</span></p>
<p id="locationWrapper">Location: <span id="location">…</span></p>
<p id="distanceWrapper">Distance Traveled: <span id="distance">…</span><br /><button onclick="offerToSaveTripLog(tripLog);">Save Trip Log</button></p>
</div>
<p id="tripLogLinkWrapper"></p>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment