Add list sorting: distance, number, street
This commit is contained in:
		
							parent
							
								
									63f1ac770f
								
							
						
					
					
						commit
						c3f9c19280
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,2 +1,5 @@ | |||||||
| /node_modules/ | /node_modules/ | ||||||
| /www/node_modules/ | /www/node_modules/ | ||||||
|  | /platforms | ||||||
|  | /nbproject/private | ||||||
|  | /plugins | ||||||
							
								
								
									
										10
									
								
								www/assets/css/backdrop.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								www/assets/css/backdrop.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | /* | ||||||
|  |     We want the backdrops to be there so there aren't accidental touches, | ||||||
|  |     but we don't want them to obscure anything. | ||||||
|  | */ | ||||||
|  | .actions-backdrop.backdrop-in, .custom-modal-backdrop.backdrop-in, | ||||||
|  | .dialog-backdrop.backdrop-in, .popover-backdrop.backdrop-in, | ||||||
|  | .popup-backdrop.backdrop-in, .preloader-backdrop.backdrop-in, | ||||||
|  | .sheet-backdrop.backdrop-in { | ||||||
|  |     opacity: 0; | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								www/assets/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								www/assets/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -38,28 +38,96 @@ $(".view-main").on("swipeout:delete", "#addresslist .package-list-item", functio | |||||||
|     deletePackage($(this).data("packageid")); |     deletePackage($(this).data("packageid")); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| function loadPackageList() { | /** | ||||||
|  |  * Update package distances relative to the passed coordinates. | ||||||
|  |  * @param {type} latitude | ||||||
|  |  * @param {type} longitude | ||||||
|  |  * @returns {undefined} | ||||||
|  |  */ | ||||||
|  | function updateDistances(latitude, longitude) { | ||||||
|  |     for (var i = 0; i < packages.length; i++) { | ||||||
|  |         var distance = getDistance(latitude, longitude, packages[i].coords[0], packages[i].coords[1]).toFixed(0); | ||||||
|  |         packages[i].distance = distance; | ||||||
|  |         $("#addresslist .package-list-item[data-packageid=\"" + i + "\"] .item-content").data("distance", distance); | ||||||
|  |         $("#addresslist .package-list-item[data-packageid=\"" + i + "\"] .item-content .distance").text(distance + " m"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function loadPackageList(sortType) { | ||||||
|  |     // If no sort type is specified, use the saved pref or a default one
 | ||||||
|  |     if (typeof sortType == 'undefined') { | ||||||
|  |         if (localStorage.getItem("sorttype") == null) { | ||||||
|  |             localStorage.setItem("sorttype", "distance_asc"); | ||||||
|  |         } | ||||||
|  |         sortType = localStorage.getItem("sorttype"); | ||||||
|  |     } else { | ||||||
|  |         // save the current sorting order so it'll stay consistent next time the list is refreshed
 | ||||||
|  |         localStorage.setItem("sorttype", sortType); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     updateDistances(userPosition.coords.latitude, userPosition.coords.longitude); | ||||||
|  | 
 | ||||||
|  |     var sortedPackages = packages.map(function (el, i) { | ||||||
|  |         return {index: i, value: el}; | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     sortedPackages.sort(function (a, b) { | ||||||
|  |         var aalpha = a.value.address.substr(a.value.address.indexOf(' ') + 1); | ||||||
|  |         var balpha = b.value.address.substr(b.value.address.indexOf(' ') + 1); | ||||||
|  |         var anum = parseInt(a.value.address.split(" ", 1)[0], 10); | ||||||
|  |         var bnum = parseInt(b.value.address.split(" ", 1)[0], 10); | ||||||
|  | 
 | ||||||
|  |         console.log("aalpha", aalpha); | ||||||
|  |         console.log("balpha", balpha); | ||||||
|  |         switch (sortType) { | ||||||
|  |             case "alpha_desc": | ||||||
|  |                 if (aalpha > balpha) { | ||||||
|  |                     return -1; | ||||||
|  |                 } else if (aalpha < balpha) { | ||||||
|  |                     return 1; | ||||||
|  |                 } | ||||||
|  |                 return 0; | ||||||
|  |             case "alpha_asc": | ||||||
|  |                 if (aalpha > balpha) { | ||||||
|  |                     return 1; | ||||||
|  |                 } else if (aalpha < balpha) { | ||||||
|  |                     return -1; | ||||||
|  |                 } | ||||||
|  |                 return 0; | ||||||
|  |             case "number_desc": | ||||||
|  |                 return bnum - anum; | ||||||
|  |             case "number_asc": | ||||||
|  |                 return anum - bnum; | ||||||
|  |             case "distance_desc": | ||||||
|  |                 return b.value.distance - a.value.distance; | ||||||
|  |             case "distance_asc": | ||||||
|  |             default: | ||||||
|  |                 return a.value.distance - b.value.distance; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|     $("#addresslist").html(""); |     $("#addresslist").html(""); | ||||||
| 
 | 
 | ||||||
|     for (var i = 0; i < packages.length; i++) { |     for (var i = 0; i < sortedPackages.length; i++) { | ||||||
|         var icon = "fas fa-box-open"; |         var icon = "fas fa-box-open"; | ||||||
|         var classes = ""; |         var classes = ""; | ||||||
|         if (packages[i].delivered == true) { |         if (sortedPackages[i].value.delivered == true) { | ||||||
|             icon = "fas fa-check"; |             icon = "fas fa-check"; | ||||||
|             classes = "text-color-green"; |             classes = "text-color-green"; | ||||||
|         } |         } | ||||||
|         $("#addresslist").append( |         $("#addresslist").append( | ||||||
|                 '<li class="swipeout package-list-item" data-packageid="' + i + '">' |                 '<li class="swipeout package-list-item" data-packageid="' + sortedPackages[i].index + '">' | ||||||
|                 + '<div class="item-content swipeout-content ' + classes + '" data-packageid="' + i + '" data-latitude="' + packages[i].coords[0] + '" data-longitude="' + packages[i].coords[1] + '">' |                 + '<div class="item-content swipeout-content ' + classes + '" data-packageid="' + sortedPackages[i].index + '" data-latitude="' + sortedPackages[i].value.coords[0] + '" data-longitude="' + sortedPackages[i].value.coords[1] + '">' | ||||||
|                 + '  <div class="item-media">' |                 + '  <div class="item-media">' | ||||||
|                 + '    <i class="icon ' + icon + '"></i>' |                 + '    <i class="icon ' + icon + '"></i>' | ||||||
|                 + '  </div>' |                 + '  </div>' | ||||||
|                 + '  <div class="item-inner">' |                 + '  <div class="item-inner">' | ||||||
|                 + '    <div class="item-title">' |                 + '    <div class="item-title">' | ||||||
|                 + '       ' + packages[i].address |                 + '       ' + sortedPackages[i].value.address | ||||||
|                 + '    </div>' |                 + '    </div>' | ||||||
|                 + '    <div class="item-footer">' |                 + '    <div class="item-footer">' | ||||||
|                 + '      <span class="distance">... m</span>' |                 + '      <span class="distance">' + (typeof sortedPackages[i].value.distance != 'undefined' ? sortedPackages[i].value.distance : '...') + ' m</span>' | ||||||
|                 + '    </div>' |                 + '    </div>' | ||||||
|                 + '  </div>' |                 + '  </div>' | ||||||
|                 + '</div>' |                 + '</div>' | ||||||
| @ -73,19 +141,19 @@ function loadPackageList() { | |||||||
| 
 | 
 | ||||||
| function confirmDeleteAllPackages() { | function confirmDeleteAllPackages() { | ||||||
|     app.dialog.confirm( |     app.dialog.confirm( | ||||||
|                 "Really delete all packages from list?", |             "Really delete all packages from list?", | ||||||
|                 "Clear Packages", |             "Clear Packages", | ||||||
|                 function () { |             function () { | ||||||
|                     // clear
 |                 // clear
 | ||||||
|                     packages = []; |                 packages = []; | ||||||
|                     localStorage.setItem("packages", JSON.stringify(packages)); |                 localStorage.setItem("packages", JSON.stringify(packages)); | ||||||
|                     loadPackageList(); |                 loadPackageList(); | ||||||
|                     if (map != null) { |                 if (map != null) { | ||||||
|                         map.updatePackageLayer(packages); |                     map.updatePackageLayer(packages); | ||||||
|                     } |  | ||||||
|                 }, |  | ||||||
|                 function () { |  | ||||||
|                     // cancel
 |  | ||||||
|                 } |                 } | ||||||
|         ); |             }, | ||||||
|  |             function () { | ||||||
|  |                 // cancel
 | ||||||
|  |             } | ||||||
|  |     ); | ||||||
| } | } | ||||||
							
								
								
									
										135
									
								
								www/assets/js/location.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								www/assets/js/location.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,135 @@ | |||||||
|  | /* | ||||||
|  |  * To change this license header, choose License Headers in Project Properties. | ||||||
|  |  * To change this template file, choose Tools | Templates | ||||||
|  |  * and open the template in the editor. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | var lastGpsUpdateTimestamp = 0; | ||||||
|  | 
 | ||||||
|  | var userPosition = { | ||||||
|  |     coords: { | ||||||
|  |         latitude: 0.0, | ||||||
|  |         longitude: 0.0, | ||||||
|  |         accuracy: 999999 | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | var geoerrorcount = 0; | ||||||
|  | 
 | ||||||
|  | var mapLocationControlStarted = false; | ||||||
|  | 
 | ||||||
|  | if ("geolocation" in navigator) { | ||||||
|  |     navigator.geolocation.watchPosition(function (position) { | ||||||
|  |         userPosition = position; | ||||||
|  |         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); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 lastGpsUpdateTimestamp = currentTimestamp; | ||||||
|  |                 for (var i = 0; i < packages.length; i++) { | ||||||
|  |                     if (packages[i].distance * 1 < localStorage.getItem("alertradius") * 1) { | ||||||
|  | 
 | ||||||
|  |                         if (packages[i].lastAlert > currentTimestamp - 30) { | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if (packages[i].delivered) { | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         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; | ||||||
|  | } | ||||||
| @ -19,6 +19,9 @@ var app = new Framework7({ | |||||||
|     popup: { |     popup: { | ||||||
|         backdrop: true |         backdrop: true | ||||||
|     }, |     }, | ||||||
|  |     popover: { | ||||||
|  |         backdrop: true | ||||||
|  |     }, | ||||||
|     init: true, |     init: true, | ||||||
|     initOnDeviceReady: false, |     initOnDeviceReady: false, | ||||||
|     routes: routes |     routes: routes | ||||||
| @ -49,9 +52,9 @@ router.on("pageInit", function (pagedata) { | |||||||
| 
 | 
 | ||||||
| router.on("routeChange", function (newRoute) { | router.on("routeChange", function (newRoute) { | ||||||
|     console.log(newRoute); |     console.log(newRoute); | ||||||
|    if (newRoute == "home") { |     if (newRoute == "home") { | ||||||
|        router.refreshPage(); |         router.refreshPage(); | ||||||
|    } |     } | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| // Set alert radius to 100 meters by default
 | // Set alert radius to 100 meters by default
 | ||||||
| @ -59,4 +62,8 @@ if (localStorage.getItem("alertradius") == null) { | |||||||
|     localStorage.setItem("alertradius", 100); |     localStorage.setItem("alertradius", 100); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | if (localStorage.getItem("darktheme") == true) { | ||||||
|  |     $("#app").addClass("theme-dark"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| router.navigate("/home"); | router.navigate("/home"); | ||||||
| @ -4,21 +4,6 @@ | |||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 |  * 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 |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| var geoerrorcount = 0; |  | ||||||
| 
 |  | ||||||
| var gotfirstfix = false; |  | ||||||
| 
 |  | ||||||
| var map = null; | var map = null; | ||||||
| 
 | 
 | ||||||
| function createMap() { | function createMap() { | ||||||
| @ -74,82 +59,6 @@ function openPackageInfoSheet(package, refreshOnly) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** |  | ||||||
|  * TODO: make app location work before map is opened for first time |  | ||||||
|  */ |  | ||||||
| if ("geolocation" in navigator) { |  | ||||||
|     navigator.geolocation.watchPosition(function (position) { |  | ||||||
|         userPosition = position; |  | ||||||
|         if (gotfirstfix) { |  | ||||||
|             //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); |  | ||||||
|                 map.updatePackageLayer(packages); |  | ||||||
|                 lastGpsUpdateTimestamp = currentTimestamp; |  | ||||||
|                 for (var i = 0; i < packages.length; i++) { |  | ||||||
|                     if (packages[i].distance * 1 < localStorage.getItem("alertradius") * 1) { |  | ||||||
| 
 |  | ||||||
|                         if (packages[i].lastAlert > currentTimestamp - 30) { |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         if (packages[i].delivered) { |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         playSound("alert"); |  | ||||||
| 
 |  | ||||||
|                         packages[i].lastAlert = currentTimestamp; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             if (map == null) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             map.locateControl.start(); |  | ||||||
|             gotfirstfix = 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 |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Update package distances relative to the passed coordinates. |  | ||||||
|  * @param {type} latitude |  | ||||||
|  * @param {type} longitude |  | ||||||
|  * @returns {undefined} |  | ||||||
|  */ |  | ||||||
| function updateDistances(latitude, longitude) { |  | ||||||
|     for (var i = 0; i < packages.length; i++) { |  | ||||||
|         var distance = getDistance(latitude, longitude, packages[i].coords[0], packages[i].coords[1]).toFixed(0); |  | ||||||
|         packages[i].distance = distance; |  | ||||||
|         $("#addresslist .package-list-item[data-latitude=\"" + packages[i].coords[0] + "\"][data-longitude=\"" + packages[i].coords[1] + "\"]").data("distance", distance); |  | ||||||
|         $("#addresslist .package-list-item[data-latitude=\"" + packages[i].coords[0] + "\"][data-longitude=\"" + packages[i].coords[1] + "\"] .distance").text(distance + " m"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function setMapLocation(latitude, longitude) { | function setMapLocation(latitude, longitude) { | ||||||
|     if (map == null) { |     if (map == null) { | ||||||
|         return; |         return; | ||||||
| @ -169,58 +78,3 @@ function animateMapIn(latitude, longitude, zoom, heading) { | |||||||
|     } |     } | ||||||
|     map.animateMapIn(latitude, longitude, zoom, heading); |     map.animateMapIn(latitude, longitude, zoom, heading); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 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; |  | ||||||
| } |  | ||||||
| @ -6,8 +6,9 @@ | |||||||
| <link rel="stylesheet" href="assets/fontawesome/css/all.min.css" /> | <link rel="stylesheet" href="assets/fontawesome/css/all.min.css" /> | ||||||
| <link rel="stylesheet" href="node_modules/leaflet/dist/leaflet.css" /> | <link rel="stylesheet" href="node_modules/leaflet/dist/leaflet.css" /> | ||||||
| <link rel="stylesheet" href="node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css" /> | <link rel="stylesheet" href="node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css" /> | ||||||
|  | <link rel="stylesheet" href="assets/css/backdrop.css" /> | ||||||
| 
 | 
 | ||||||
| <div id="app" class="color-theme-blue theme-dark"> | <div id="app" class="color-theme-blue"> | ||||||
| 
 | 
 | ||||||
|     <div class="view view-main"></div> |     <div class="view view-main"></div> | ||||||
| 
 | 
 | ||||||
| @ -28,6 +29,7 @@ | |||||||
| 
 | 
 | ||||||
| <script src="assets/js/audio.js"></script> | <script src="assets/js/audio.js"></script> | ||||||
| <script src="assets/js/packages.js"></script> | <script src="assets/js/packages.js"></script> | ||||||
|  | <script src="assets/js/location.js"></script> | ||||||
| <script src="assets/js/list.js"></script> | <script src="assets/js/list.js"></script> | ||||||
| <script src="assets/js/map_leaflet.js"></script> | <script src="assets/js/map_leaflet.js"></script> | ||||||
| <script src="assets/js/map.js"></script> | <script src="assets/js/map.js"></script> | ||||||
|  | |||||||
| @ -14,6 +14,9 @@ | |||||||
|             </div> |             </div> | ||||||
|             <div class="title">Packages</div> |             <div class="title">Packages</div> | ||||||
|             <div class="right"> |             <div class="right"> | ||||||
|  |                 <a class="link popover-open" data-popover="#popover-sort-list"> | ||||||
|  |                     <i class="icon fas fa-sort-amount-down-alt"></i> | ||||||
|  |                 </a> | ||||||
|                 <a class="link text-color-red" onclick="confirmDeleteAllPackages()"> |                 <a class="link text-color-red" onclick="confirmDeleteAllPackages()"> | ||||||
|                     <i class="icon fas fa-trash"></i> |                     <i class="icon fas fa-trash"></i> | ||||||
|                 </a> |                 </a> | ||||||
| @ -30,4 +33,19 @@ | |||||||
| 
 | 
 | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|  |     <div class="popover" id="popover-sort-list"> | ||||||
|  |         <div class="popover-inner"> | ||||||
|  |             <div class="list"> | ||||||
|  |                 <ul> | ||||||
|  |                     <li><a class="list-button item-link" href="" onclick="loadPackageList('distance_asc');">Distance (near-far)</a></li> | ||||||
|  |                     <li><a class="list-button item-link" href="" onclick="loadPackageList('distance_desc');">Distance (far-near)</a></li> | ||||||
|  |                     <li><a class="list-button item-link" href="" onclick="loadPackageList('alpha_asc');">Street (a-z)</a></li> | ||||||
|  |                     <li><a class="list-button item-link" href="" onclick="loadPackageList('alpha_asc');">Street (z-a)</a></li> | ||||||
|  |                     <li><a class="list-button item-link" href="" onclick="loadPackageList('number_asc');">Number (1-9)</a></li> | ||||||
|  |                     <li><a class="list-button item-link" href="" onclick="loadPackageList('number_desc');">Number (9-1)</a></li> | ||||||
|  |                 </ul> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
| </div> | </div> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user