forked from Netsyms/PackageHelper
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
7.5 KiB
JavaScript
223 lines
7.5 KiB
JavaScript
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
var lastGpsUpdateTimestamp = 0;
|
|
|
|
var userPosition = {
|
|
coords: {
|
|
latitude: 0.0,
|
|
longitude: 0.0,
|
|
accuracy: 999999
|
|
}
|
|
};
|
|
|
|
// Preload last known location while GPS warms up
|
|
if (localStorage.getItem("user_latitude") != null && localStorage.getItem("user_longitude") != null) {
|
|
userPosition.coords.latitude = localStorage.getItem("user_latitude");
|
|
userPosition.coords.longitude = localStorage.getItem("user_longitude");
|
|
}
|
|
|
|
// Request the user's IP geolocation as a poor substitute for an actual location
|
|
// Should improve UX for weather tool at least
|
|
$.ajax({
|
|
url: SETTINGS.geoipapi,
|
|
dataType: 'json',
|
|
timeout: 10 * 1000,
|
|
success: function (resp) {
|
|
if (resp.status == "OK" && userPosition.coords.accuracy > 99999) {
|
|
userPosition.coords.latitude = resp.location.latitude;
|
|
userPosition.coords.longitude = resp.location.longitude;
|
|
userPosition.coords.accuracy = 99999;
|
|
}
|
|
}
|
|
});
|
|
|
|
var geoerrorcount = 0;
|
|
|
|
var mapLocationControlStarted = false;
|
|
|
|
if ("geolocation" in navigator) {
|
|
navigator.geolocation.watchPosition(function (position) {
|
|
userPosition = position;
|
|
localStorage.setItem("user_latitude", userPosition.coords.latitude);
|
|
localStorage.setItem("user_longitude", userPosition.coords.longitude);
|
|
if (mapLocationControlStarted) {
|
|
//setMapLocation(position.coords.latitude, position.coords.longitude);
|
|
// Don't refresh at an interval less than ten seconds
|
|
var currentTimestamp = Math.floor(Date.now() / 1000);
|
|
if (lastGpsUpdateTimestamp < (currentTimestamp - 10)) {
|
|
updateDistances(position.coords.latitude, position.coords.longitude);
|
|
if (map != null) {
|
|
//map.updatePackageLayer(packages);
|
|
}
|
|
|
|
var alertinterval = localStorage.getItem("alertinterval");
|
|
if (alertinterval == null) {
|
|
alertinterval = 30;
|
|
} else {
|
|
alertinterval = alertinterval * 1;
|
|
}
|
|
|
|
lastGpsUpdateTimestamp = currentTimestamp;
|
|
for (var i = 0; i < packages.length; i++) {
|
|
if (packages[i].distance * 1 < localStorage.getItem("alertradius") * 1) {
|
|
|
|
if (packages[i].lastAlert > currentTimestamp - alertinterval) {
|
|
continue;
|
|
}
|
|
|
|
if (getUndeliveredCount(packages[i]) == 0) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
if (map != null) {
|
|
map.updatePackageLayer(packages);
|
|
}
|
|
loadPackageList();
|
|
} catch (ex) {
|
|
// It'll show up sooner or later anyways
|
|
}
|
|
|
|
playSound("alert");
|
|
packages[i].lastAlert = currentTimestamp;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (map != null) {
|
|
map.locateControl.start();
|
|
mapLocationControlStarted = true;
|
|
}
|
|
}
|
|
}, function (err) {
|
|
if (typeof error == "function") {
|
|
error(err.message);
|
|
}
|
|
}, {
|
|
enableHighAccuracy: true,
|
|
timeout: 5000,
|
|
maximumAge: 0
|
|
});
|
|
} else {
|
|
geoerrorcount++;
|
|
console.log("Geolocation error #" + geoerrorcount + ": ", error);
|
|
// Stop showing error toasts if they're happening a lot
|
|
if (geoerrorcount <= 3) {
|
|
app.toast.show({
|
|
text: '<i class="fas fa-compass"></i> ' + error,
|
|
position: "bottom",
|
|
destroyOnClose: true,
|
|
closeTimeout: 1000 * 3
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate distance between two GPS points using Vincenty Formula.
|
|
*
|
|
* From Aman Singh https://stackoverflow.com/q/30536869
|
|
*
|
|
* @param {type} lat1
|
|
* @param {type} lon1
|
|
* @param {type} lat2
|
|
* @param {type} lon2
|
|
* @returns {Number} distance in meters
|
|
*/
|
|
function getDistance(lat1, lon1, lat2, lon2) {
|
|
|
|
var toRad = function (value) {
|
|
return value * Math.PI / 180;
|
|
}
|
|
|
|
var a = 6378137, b = 6356752.314245, f = 1 / 298.257223563;
|
|
var L = toRad(lon2 - lon1);
|
|
var U1 = Math.atan((1 - f) * Math.tan(toRad(lat1)));
|
|
var U2 = Math.atan((1 - f) * Math.tan(toRad(lat2)));
|
|
var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
|
|
var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
|
|
|
|
var lambda = L, lambdaP, iterLimit = 100;
|
|
do
|
|
{
|
|
var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
|
|
var sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
|
|
if (sinSigma == 0)
|
|
return 0;
|
|
|
|
var cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
|
|
var sigma = Math.atan2(sinSigma, cosSigma);
|
|
var sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
|
|
var cosSqAlpha = 1 - sinAlpha * sinAlpha;
|
|
var cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
|
|
if (isNaN(cos2SigmaM))
|
|
cos2SigmaM = 0;
|
|
var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
|
|
lambdaP = lambda;
|
|
lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
|
|
} while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);
|
|
|
|
if (iterLimit == 0)
|
|
return NaN
|
|
|
|
var uSq = cosSqAlpha * (a * a - b * b) / (b * b);
|
|
var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
|
var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
|
var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
|
|
var s = b * A * (sigma - deltaSigma);
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Return a formatted string with units corresponding to a number of meters.
|
|
* Respects user "units" setting ("metric" or "imperial").
|
|
* @param number meters
|
|
* @param bool space Add a space between number and units. Default true.
|
|
* @returns string "1000 ft", "2 mi", "3 km",
|
|
*/
|
|
function getDisplayDistance(meters, space) {
|
|
if (typeof space == 'undefined') {
|
|
space = true;
|
|
}
|
|
var units = localStorage.getItem("units");
|
|
|
|
if (units == null) {
|
|
units = "metric";
|
|
}
|
|
|
|
var number = Math.round(meters);
|
|
var label = "m";
|
|
|
|
if (units == "imperial") {
|
|
// Convert to feet
|
|
number = Math.round(number * 3.28084);
|
|
label = "ft";
|
|
if (number >= 1320) { // 0.25 miles
|
|
number = (number / 5280);
|
|
if (number < 10) {
|
|
number = number.toFixed(2);
|
|
} else {
|
|
number = Math.round(number);
|
|
}
|
|
label = "mi";
|
|
}
|
|
} else {
|
|
if (number >= 1000) {
|
|
number = (number / 1000);
|
|
if (number < 16) {
|
|
number = number.toFixed(1);
|
|
} else {
|
|
number = Math.round(number);
|
|
}
|
|
label = "km";
|
|
}
|
|
}
|
|
|
|
if (space) {
|
|
return number + " " + label;
|
|
}
|
|
return number + "" + label;
|
|
} |