mirror of
https://github.com/owntracks/recorder.git
synced 2026-05-05 02:36:45 +00:00
303 lines
8.9 KiB
HTML
303 lines
8.9 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>OwnTracks View</title>
|
|
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, initial-scale=1.0" />
|
|
|
|
<meta name="mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<link rel="manifest" href="manifest.json">
|
|
<style type="text/css">
|
|
html { height: 100%; }
|
|
body { height: 100%; margin: 0px; padding: 0px; }
|
|
#map-canvas { height: 100%; }
|
|
|
|
.extrainfo { font-size: 80%; }
|
|
.latlon { color: gray; }
|
|
.block1 { float: left; }
|
|
.block2 { border 1px solid; background-color: white; width: 40px; height: 40px; float: right; margin-left: 20px; margin-right: 0px; padding-right: 0; }
|
|
.img-circle { border-radius: 50%; border: 1px solid #CACACA; }
|
|
</style>
|
|
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
|
|
<script src="../static/js/jquery-1.12.0.min.js"></script>
|
|
<script src="../static/js/jquery-migrate-1.2.1.min.js"></script>
|
|
<script src="../static/js/moment.min.js"></script>
|
|
<script src="../static/js/mustache.js"></script>
|
|
<script>
|
|
var map;
|
|
var markers = {};
|
|
var devices = [];
|
|
var refresh = 60000;
|
|
var livemarkers = true;
|
|
var do_fit = false;
|
|
|
|
function clog(upd, id, s) {
|
|
var ident = id || 'unknown';
|
|
console.log(upd + " " + Math.round(new Date().getTime()/1000.0) + ": " + ident + " " + s);
|
|
}
|
|
|
|
function setmarkers() {
|
|
for (var n = 0; n < devices.length; n++) {
|
|
map_marker(devices[n]);
|
|
}
|
|
}
|
|
|
|
function reload() {
|
|
getdata();
|
|
setmarkers();
|
|
setTimeout(reload, refresh);
|
|
}
|
|
|
|
function getdata() {
|
|
|
|
var json = (function () {
|
|
var json = null;
|
|
$.ajax({
|
|
'type' : 'GET',
|
|
'async': false,
|
|
'cache' : false,
|
|
'global': true,
|
|
'url' : '@@@LASTPOS@@@',
|
|
'dataType': "json",
|
|
'success': function (data) {
|
|
json = data['data'];
|
|
console.log("DATA = " + JSON.stringify(json));
|
|
devices = [];
|
|
for (var n = 0; n < json.length; n++) {
|
|
console.log(json[n]);
|
|
devices.push(json[n]);
|
|
}
|
|
return (json.length);
|
|
},
|
|
'error': function (xhr, text, error) {
|
|
console.log(error);
|
|
return (-1);
|
|
}
|
|
});
|
|
})();
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* The TrackControl adds a control to the map that loads the GeoJSON track.
|
|
* This constructor takes the track DIV as an argument.
|
|
*/
|
|
function TrackControl(controlDiv, map) {
|
|
|
|
// Set CSS for the control border
|
|
var controlUI = document.createElement('div');
|
|
controlUI.style.backgroundColor = '#fff';
|
|
controlUI.style.border = '2px solid #fff';
|
|
controlUI.style.borderRadius = '3px';
|
|
controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
|
|
controlUI.style.cursor = 'pointer';
|
|
controlUI.style.marginBottom = '22px';
|
|
controlUI.style.textAlign = 'center';
|
|
controlUI.title = 'Click to load the track onto the map';
|
|
controlDiv.appendChild(controlUI);
|
|
|
|
// Set CSS for the control interior
|
|
var controlText = document.createElement('div');
|
|
controlText.style.color = 'rgb(25,25,25)';
|
|
controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
|
|
controlText.style.fontSize = '16px';
|
|
controlText.style.lineHeight = '38px';
|
|
controlText.style.paddingLeft = '5px';
|
|
controlText.style.paddingRight = '5px';
|
|
controlText.innerHTML = 'Load track';
|
|
controlUI.appendChild(controlText);
|
|
|
|
// Setup the click event listeners: simply set the map to
|
|
// Chicago
|
|
google.maps.event.addDomListener(controlUI, 'click', function() {
|
|
|
|
map.data.loadGeoJson('@@@GEO@@@');
|
|
|
|
// Set the stroke width, and fill color for each polygon
|
|
var featureStyle = {
|
|
strokeColor: 'red',
|
|
strokeWeight: 4,
|
|
}
|
|
map.data.setStyle(featureStyle);
|
|
});
|
|
|
|
}
|
|
|
|
function initialize() {
|
|
var lat;
|
|
var lon;
|
|
|
|
if (getdata() < 1) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
lat = devices[0].lat;
|
|
lon = devices[0].lon;
|
|
tst = devices[0].tst;
|
|
} catch (err) {
|
|
document.write("NO data");
|
|
return;
|
|
}
|
|
|
|
// FIXME: we can use "center" from VIEW to nail the map
|
|
|
|
var center = new google.maps.LatLng(lat,lon);
|
|
|
|
mapOptions = {
|
|
center: center,
|
|
zoom: devices[0].zoom ? devices[0].zoom : 9,
|
|
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
|
scrollwheel: false,
|
|
disableDefaultUI: false,
|
|
panControl: false,
|
|
scaleControl: false,
|
|
streetViewControl: true,
|
|
overviewMapControl: true,
|
|
};
|
|
|
|
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
|
|
|
|
// Create the DIV to hold the control and call the TrackControl()
|
|
// constructor passing in this DIV.
|
|
|
|
var trackControlDiv = document.createElement('div');
|
|
var trackControl = new TrackControl(trackControlDiv, map);
|
|
|
|
trackControlDiv.index = 1;
|
|
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(trackControlDiv);
|
|
|
|
|
|
setmarkers()
|
|
setTimeout(reload, refresh);
|
|
}
|
|
|
|
/*
|
|
* Close all the infowindows in the `markers' object, and then open the
|
|
* infowindow in the specified marker.
|
|
*/
|
|
|
|
function refreshmarkers(m) {
|
|
for (var k in markers) {
|
|
markers[k]['infowindow'].close();
|
|
}
|
|
m['infowindow'].open(map, m);
|
|
}
|
|
|
|
function fitbounds() {
|
|
var bounds = new google.maps.LatLngBounds();
|
|
for (var k in markers) {
|
|
bounds.extend(markers[k].getPosition());
|
|
}
|
|
map.setCenter(bounds.getCenter()); /* Center to geometric center of all markers */
|
|
map.fitBounds(bounds);
|
|
}
|
|
|
|
/*
|
|
* `loc' is a location object obtained from the Recorder, with some extra bits
|
|
* included from the view's configuration
|
|
*/
|
|
|
|
function map_marker(loc)
|
|
{
|
|
var id = loc.tid;
|
|
var htmldesc;
|
|
var shortdesc;
|
|
var dt = moment.utc(loc.tst * 1000).local();
|
|
|
|
var userdev = loc.label ? loc.label : loc.tid;
|
|
|
|
if (loc.name) {
|
|
userdev = loc.name; /* override label/tid by name from CARD */
|
|
}
|
|
|
|
var data = {
|
|
userdev: userdev,
|
|
ghash: loc.ghash ? loc.ghash : '',
|
|
addr: loc.addr,
|
|
lat: loc.lat,
|
|
lon: loc.lon,
|
|
fulldate: dt.format("DD MMM YYYY HH:mm:ss"),
|
|
facedata: loc.face,
|
|
};
|
|
|
|
if (loc.addr) {
|
|
htmldesc = "<div class='block1'><b>{{userdev}}</b><br/>{{addr}}<br/><span class='extrainfo'>{{ghash}} <span class='latlon'>({{lat}},{{lon}})</span> {{fulldate}}</span>";
|
|
|
|
|
|
shortdesc = "{{userdev}} {{addr}}";
|
|
} else {
|
|
htmldesc = "<div class='block1'><b>{{userdev}}</b><br/>{{lat}}, {{lon}}<br/><span class='extrainfo'>{{ghash}} <span class='latlon'>({{lat}},{{lon}})</span> {{fulldate}}</span>";
|
|
shortdesc = "{{userdev}} {{lat}},{{lon}}";
|
|
}
|
|
|
|
|
|
if (loc.face) {
|
|
htmldesc = htmldesc + "</div><div class='block2' id='avatar'><img class='img-circle' src='data:image/png;base64,{{ facedata }}' height='35' width='35' /></div>";
|
|
} else {
|
|
htmldesc = htmldesc + "</div><div class='block2' id='avatar'></div>";
|
|
}
|
|
|
|
loc.description = Mustache.render(shortdesc, data);
|
|
loc.htmldesc = Mustache.render(htmldesc, data);
|
|
|
|
if (markers.hasOwnProperty(id)) {
|
|
clog("UPD", id, JSON.stringify(loc));
|
|
m = markers[id];
|
|
var LatLng = new google.maps.LatLng(loc.lat, loc.lon);
|
|
m.setPosition(LatLng);
|
|
m.setTitle(loc.description);
|
|
|
|
/* Grab the InfoWindow of this marker and change content */
|
|
m['infowindow'].setContent(loc.htmldesc);
|
|
if (livemarkers) {
|
|
refreshmarkers(m);
|
|
}
|
|
} else {
|
|
clog("NEW", id, JSON.stringify(loc));
|
|
var circle ={
|
|
path: google.maps.SymbolPath.CIRCLE,
|
|
fillColor: '#ff0000',
|
|
fillOpacity: .9,
|
|
scale: 5.5,
|
|
strokeColor: 'white',
|
|
strokeWeight: 2
|
|
};
|
|
|
|
var LatLng = new google.maps.LatLng(loc.lat, loc.lon);
|
|
var m = new google.maps.Marker({
|
|
position: LatLng,
|
|
map: map,
|
|
title: loc.description,
|
|
icon: circle
|
|
});
|
|
|
|
/* Create a new InfoWindow for this marker, and add listener */
|
|
m['infowindow'] = new google.maps.InfoWindow({
|
|
content: loc.htmldesc
|
|
});
|
|
google.maps.event.addListener(m, "click", function(e) {
|
|
this['infowindow'].open(map, this);
|
|
});
|
|
if (livemarkers) {
|
|
refreshmarkers(m);
|
|
}
|
|
|
|
markers[id] = m;
|
|
}
|
|
|
|
if (do_fit) {
|
|
fitbounds();
|
|
}
|
|
}
|
|
|
|
|
|
google.maps.event.addDomListener(window, 'load', initialize);
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="map-canvas"></div>
|
|
</body>
|
|
</html>
|