165 lines
5.7 KiB
JavaScript
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
|