jubilee/src/v1/js/Location.js
Martin Donnelly 0bb1e1baa6 add ByMe
2018-02-27 00:01:26 +00:00

165 lines
5.7 KiB
JavaScript

const _ = require('underscore');
const Backbone = require('backbone');
const geolocation = require('geolocation');
const TimeFormat = require('hh-mm-ss');
const { distance } = require('./utils');
const NodeGeocoder = require('node-geocoder');
// const locationData = require('./location-data.json');
const LocationModel = Backbone.Model.extend({
'defaults': {
// defaults go here - "children" may be contained here
},
'tick': function() {
const p = locationData[this.pos];
const now = new Date();
console.log(p);
const location = { 'latitude': p.lat, 'longitude': p.lng, 'timestamp': now.getTime() };
this.processPosition(location);
this.timerID = setTimeout(
() => {
this.pos++;
this.tick();
},
p.time
);
},
'initialize': function() {
// this.listenTo(this, 'change sync reset', this.onChange);
const geoOptions = {
'maximumAge': 5 * 60 * 1000,
'timeout': 10 * 1000
};
this.pos = 0;
this.moveTimer = 0;
geolocation.options = geoOptions;
geolocation.on('error', function(err) {
console.warn('Geolocation error');
console.error(err);
});
geolocation.on('change', function( position) {
console.log('Location update');
const location = { 'latitude': position.coords.latitude, 'longitude': position.coords.longitude, 'timestamp': position.timestamp };
this.processPosition(location);
// this.set('location', location);
}.bind(this));
this.watcher = geolocation.createWatcher();
this.listenTo(this, 'change:location', this.onChange);
// this.tick();
},
'onChange': function() {
console.log('>> Location updated');
console.log(JSON.stringify(this.get('location')));
},
'processPosition': function(pos) {
console.log('processPosition');
const { latitude, longitude, timestamp } = pos;
const current = this.get('location');
const options = {
'provider': 'google',
// Optional depending on the providers
'httpAdapter': 'https', // Default
'apiKey': 'AIzaSyA7oGP6QS28tTwtT6UzA7hzh0b3MWwMYB8', // for Mapquest, OpenCage, Google Premier
'formatter': null // 'gpx', 'string', ...
};
const geocoder = NodeGeocoder(options);
const homeDistance = distance(55.942673, -4.556334, latitude, longitude);
const workDistance = distance(55.861939, -4.259338, latitude, longitude);
const atHome = (homeDistance < 0.10);
const atWork = (workDistance < 0.10);
const atHomeOrWork = (atHome || atWork);
const latlong = { 'lat':latitude, 'lon':longitude };
const ll = `${latitude},${longitude}`;
const llFixed = `${Number.parseFloat(latitude).toFixed(3)},${Number.parseFloat(longitude).toFixed(3)}`;
const llSix = `${Number.parseFloat(latitude).toFixed(6)},${Number.parseFloat(longitude).toFixed(6)}`;
const moving = true;
const newLocation = { homeDistance, workDistance, latitude, longitude, atHome, atWork, atHomeOrWork, timestamp, ll, llFixed, llSix, moving, 'city' : '', 'cityCC':'' };
// console.log('>> NewLocation', JSON.stringify(newLocation));
// const distanceFromLast = distance(current.latitude, current.longitude, latitude, longitude);
if (!current /* || distanceFromLast > 1.5*/)
geocoder.reverse(latlong)
.then(function(res) {
console.log(JSON.stringify(res));
newLocation.city = res[0].city;
newLocation.cityCC = `${res[0].city},${res[0].countryCode}`;
newLocation.address = res[0].formattedAddress;
this.set('location', newLocation);
this.set('moving', moving);
this.set('lastGeocode', { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp });
}.bind(this))
.catch(function(err) {
console.error(err);
this.set('location', newLocation);
});
else {
newLocation.city = current.city;
const distanceFromLast = distance(current.latitude, current.longitude, latitude, longitude);
const lastGeocode = this.get('lastGeocode');
const distanceFromLastGeocode = distance(lastGeocode.lat, lastGeocode.lng, latitude, longitude);
console.log('>> distance from last record', distanceFromLast);
console.log('>> distanceFromLastGeocode', distanceFromLastGeocode, TimeFormat.fromMs(timestamp - lastGeocode.timestamp, 'hh:mm:ss'));
if ((distanceFromLast > 0.5 && distanceFromLast < 2.0) || (timestamp - current.timestamp > 900000)) {
// dont bother re geocoding
console.log('Slightly moved from previous');
this.set('location', newLocation);
this.set('moving', moving);
}
else if (distanceFromLastGeocode >= 2.0 || (timestamp - lastGeocode.timestamp > 1.8e+6) ) {
console.log('Moved from previous', (timestamp - lastGeocode.timestamp > 1.8e+6));
geocoder.reverse(latlong)
.then(function(res) {
newLocation.city = res[0].city;
newLocation.cityCC = `${res[0].city},${res[0].countryCode}`;
newLocation.address = res[0].formattedAddress;
this.set('location', newLocation);
this.set('lastGeocode', { 'lat':latitude, 'lng':longitude, 'timestamp':timestamp });
this.set('moving', moving);
}.bind(this))
.catch(function(err) {
console.error(err);
this.set('location', newLocation);
});
}
}
clearTimeout(this.moveTimer);
this.moveTimer = setTimeout(
() => {
console.log('>>>> STOPPED MOVING');
// const location = this.get('location');
// location.moving = false;
this.set('moving', false);
console.log(this);
},
30000
);
}
});
module.exports = { LocationModel };
// https://www.npmjs.com/package/node-geocoder