Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 2x 2x 2x 1x 1x 2x 4x 3x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | import iLocationData from '@/interfaces/iLocationData';
import { LocationAccessError } from '@/utils/ErrorTypes';
import assert from 'assert';
import * as Location from 'expo-location';
/**
* gets the user's location using the expo-location module
*/
export default class LocationData implements iLocationData {
/**
* Checks if the user allows the app to access their location.
* @returns true if enabled, false otherwise
*/
async isEnabled(): Promise<boolean> {
return await Location.hasServicesEnabledAsync();
}
/**
* Get the user's last known location.
* @returns [latitude, longitude]. `latitude` must be from -90 to 90.
* `longitude` must be from -180 to 180.
* @throws LocationAccessError if it cannot access the user's location.
*/
async getLocation(): Promise<[number, number]> {
let location = await Location.getLastKnownPositionAsync();
if (location == null) {
throw new LocationAccessError("Cannot access user's location");
}
return [location.coords.latitude, location.coords.longitude];
}
/**
* Request access to user location data.
* @returns true if permission is granted, false otherwise.
*/
async requestPermission(): Promise<boolean> {
return (await Location.requestForegroundPermissionsAsync()).granted;
}
/**
* Returns the distance between 2 latitude and longatude coordinates.
* Modified from:
* https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula
* @param l1 List with [latitude, longatude]. Latitude must be between -90 and 90 degrees.
* Longatude must be between must be between -180 and 180 degrees.
* @param l1 List with [latitude, longatude]. Latitude must be between -90 and 90 degrees.
* Longatude must be between must be between -180 and 180 degrees.
* @returns The distance between the 2 points in kilometers.
*/
compareLocations(l1: [number, number], l2: [number, number]): number {
assert(l1[0] >= -90 && l1[0] <= 90, "Latitude of `l1` must be between -90 and 90 degrees");
assert(l1[1] >= -180 && l1[1] <= 180, "Longitude of `l1` must be between -180 and 180 degrees");
assert(l2[0] >= -90 && l2[0] <= 90, "Latitude of `l2` must be between -90 and 90 degrees");
assert(l2[1] >= -180 && l2[1] <= 180, "Longitude of `l2` must be between -180 and 180 degrees");
const R = 6371; // Radius of the earth in km
const dLat = (l1[0]-l2[0]) * (Math.PI/180); // Convert distance from degrees to radians
const dLon = (l1[1]-l2[1]) * (Math.PI/180);
const a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(l1[0] * (Math.PI/180)) * Math.cos(l2[0] * (Math.PI/180)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
const distance = R * c; // Distance in km
assert(distance >= 0, "distance should not be negative");
assert(distance <= 40075 / 2, "distance should not be greater than half the circumference of the earth")
return distance;
}
} |