/**
* @file Location API
*/
/**
* Location API
* @class
* @classdesc Gets location and name of place
* @constructor
* @param {object} weather - Weather object.
* @param {number} [latitude = current location latitude] - Latitude of location, from where weather data will be acquired.
* @param {number} [longitude = current location longitude] - Longitude of location, from where weather data will be acquired.
*/
function Location(weather, latitude, longitude) {
/**
* {@link Weather} object
* @public
*/
this.weather = weather;
/**
* Name of the city of current location
*@public
*/
this.city;
/**
* Time when location was updated.
* @public
*/
this.timeOfLastLocation = new Date(); // time of last location update
//Setting latitude and longitude, if not in arguments start acquiring
if (latitude === undefined || longitude === undefined) {
this.latitude = 0;
this.longitude = 0;
this.acquireLocation();
} else {
setLocation(latitude,longitude);
}
setInterval(function () { this.updateLocation }.bind(this), 1000 * 10); //interval to check if enough time passed to update weather and location
}
/**
* Location prototype
*/
Location.prototype = {
constructor: Location,
/**
* Method called from 10 seconds timer
*/
updateLocation: function (){
//console.log("t" + (new Date().getTime() / 1000 / 60 - this.timeOfLastLocation.getTime() / 1000 / 60));
this.acquireLocation();
},
/**
* Starts getting current location
*/
acquireLocation: function () {
//console.log("updejtam poziicjo");
//try gps location
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(
function (position) {
var toMinutes = 1 / 60000;
if ((new Date().getTime() *toMinutes - this.timeOfLastLocation.getTime() *toMinutes) > 30) {
this.setLocation(position.coords.latitude, position.coords.longitude);
console.log("NEW WEATHER BECAUSE OF TIME ELAPSED SINCE LAST UPDATE");
} else {
if (this.isNewUpdateRequired(position.coords.latitude, position.coords.longitude)) {
this.setLocation(position.coords.latitude, position.coords.longitude);
console.log("NEW LOCATION; BECAUSE TO FAR AWAY");
}
}
}.bind(this),
//if gps not enabled, ip tracking
function () {
this.acquireLocationIP();
}.bind(this));
//if gps not enabled, ip tracking
} else {
this.acquireLocationIP();
}
},
/**
* Acquires location from device ip address
*/
acquireLocationIP: function () {
console.log("Updejtam ip lokacijo");
//ajax ip location call
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var data = JSON.parse(xmlhttp.responseText);
//alert(data);
if (this.isNewUpdateRequired(data.latitude, data.longitude)) {
this.setLocation(data.latitude, data.longitude);
}
}
}.bind(this);
xmlhttp.open("GET", "http://freegeoip.net/json/", true);
xmlhttp.send();
},
/**
* Sets latitude and longitude from received data.
* @params {number} latitude - Latitdue of current location.
* @params {number} longitude - Longitude of current location.
*/
setLocation: function (latitude, longitude) {
this.latitude = latitude;
this.longitude = longitude;
this.timeOfLastLocation = new Date();//Save time when location was set
this.getLocationName();
},
/**
* Gets name of acquired location based on geolocation with reverse-geocoding API
*/
getLocationName: function () {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var data = JSON.parse(xmlhttp.responseText);
//alert(data);
this.city = data.geonames[0].adminName1;
this.weather.acquireWeatherData();
} else if (xmlhttp.status == 404) {
this.weather.acquireWeatherData();
}
}.bind(this);
xmlhttp.open("GET", "http://api.geonames.org/findNearbyPlaceNameJSON?lat="+this.latitude+"&lng="+this.longitude+"&username=pevecyan", true);
xmlhttp.send();
},
/**
* Returns true if distance between old and new location is more than 1000 meters or else
* @params {number} latitude - Latitude of the new location.
* @params {number} longitude - Longitude of the new location.
* @returns {boolean}
*/
isNewUpdateRequired: function (latitude, longitude) {
var newLatitude = latitude * (Math.PI / 180);;
var newLongitude = longitude * (Math.PI / 180);;
var oldLatitude = this.latitude * (Math.PI / 180);;
var oldLongitude = this.longitude * (Math.PI / 180);;
//calculate distance between new and old location
var distance = Math.acos(Math.sin(newLatitude) * Math.sin(oldLatitude) +
Math.cos(newLatitude) * Math.cos(oldLatitude) * Math.cos(newLongitude - oldLongitude)) * 6375;
distance = Math.floor(distance * 1000000) / 1000;
if (distance == NaN) distance = 0;
//alert(distance);
//if distance equal/more than 1000m, update location and weather
if (distance >= 1000) {
//this.setLocation(position.coords.latitude, position.coords.longitude);
return true;
console.log("NEW LOCATION; BECAUSE TO FAR AWAY");
} else {
return false;
}
}
}