Skip to content

Commit

Permalink
check if user is on the right track
Browse files Browse the repository at this point in the history
  • Loading branch information
mayfinn committed Oct 19, 2023
1 parent 606de43 commit 094e9cf
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 21 deletions.
45 changes: 45 additions & 0 deletions app/shared/utils/location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export type GeoPoint = {
latitude: number;
longitude: number;
};

/**
* Constant for the earth radius in metres.
*/
const EARTH_RADIUS = 6371e3;

/**
* Returns the distance between two points in metres.
* @see https://www.movable-type.co.uk/scripts/latlong.html
*
* @description
* This uses the haversine formula to calculate the distance
* between two points.
* a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
* c = 2 ⋅ atan2( √a, √(1−a) )
* d = R ⋅ c
* where
* φ is latitude,
* λ is longitude,
* R is earth’s radius (mean radius = 6,371km);
* note that angles need to be in radians to pass to trig functions!
*
* @param {GeoPoint} point1
* @param {GeoPoint} point2
* @returns {number} distance in metres
*/
export function distance(point1: GeoPoint, point2: GeoPoint): number {
const φ1 = (point1.latitude * Math.PI) / 180; // φ, λ in radians
const φ2 = (point2.latitude * Math.PI) / 180;
const Δφ = ((point2.latitude - point1.latitude) * Math.PI) / 180;
const Δλ = ((point2.longitude - point1.longitude) * Math.PI) / 180;

const a =
Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

const d = EARTH_RADIUS * c; // in metres

return d;
}
122 changes: 101 additions & 21 deletions app/views/liveView/Main.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@
import { onMount } from "svelte";
import { showModal } from "svelte-native";
import { tick } from "svelte";
import { confirm } from "@nativescript/core/ui/dialogs";
import { confirm, action } from "@nativescript/core/ui/dialogs";
import {
tabIndex,
liveJourney,
multiModality,
currentLocation,
watchLocation,
TimeAndPlace,

Check failure on line 12 in app/views/liveView/Main.svelte

View workflow job for this annotation

GitHub Actions / lint

'TimeAndPlace' is defined but never used
} from "~/stores";
import { routeApi } from "~/api";
import { speak } from "~/shared/utils/tts";
import { playSound } from "~/shared/utils/index";
import { transportTypeToIcon } from "~/shared/utilites";
import { getNextStep } from "~/shared/utils/liveSections";
import { distance } from "~/shared/utils/location";
import Contacts from "./Contacts.svelte";
import RouteOverview from "./RouteOverview.svelte";
Expand All @@ -25,14 +27,65 @@
onMount(() => {
watchLocation.start();
let intervalId = setInterval(() => {
if (
$liveJourney?.isPaused ||
$liveJourney?.isCompleted ||
nextReachableLocation === null
) {
return;
}
const { lat: nextLat, lng: nextLng } = nextReachableLocation;
const { latitude: currentLat, longitude: currentLng } =
$currentLocation.data;
if (nextReachableLocation.timestamp.getTime() - Date.now() <= 0) {
if (
distance(
{ latitude: nextLat, longitude: nextLng },
{ latitude: currentLat, longitude: currentLng },
) > 50
) {
const actions = [
"Alles ist in Ordnung",
"Route von hier aus neu berechnen",
];
const destructiveActionsIndexes = [1];
action({
title: "Bist du bereits an deinem Zwichenziel?",
message:
"Nach unserer Berechnung bist du noch nicht an deinem Zwischenziel angekommen. Wenn nicht erreichst du womöglich nicht deinen Anschluss. Wie möchtest du fortfahren?",
actions,
destructiveActionsIndexes,
}).then((result) => {
if (result === actions[0]) {
skipToNextStep();
} else {
calculateNewJourney = recalculateJourney();
}
});
} else {
skipToNextStep();
}
}
}, 1000);
return () => {
watchLocation.stop();
clearInterval(intervalId);
};
});
$: currentSection = $liveJourney?.sections[$liveJourney.currentSection];
let nextReachableLocation: null | { lat: number; lng: number } = null;
let nextReachableLocation: null | {
lat: number;
lng: number;
timestamp: Date;
} = null;
$: if ($liveJourney?.isPaused === false) {
const {
currentSection: currentSectionId,
Expand All @@ -52,19 +105,22 @@
if (nextStep !== null) {
const nextSection = sections[nextStep.sectionId];
const currentSection = sections[currentSectionId];
if (nextSection && nextSection?.intermediateStops) {
nextReachableLocation =
nextSection.intermediateStops[nextStep.intermediateStopId].departure
.place.location;
} else if (currentSection) {
nextReachableLocation = currentSection.arrival.place.location;
const intermediateStops = (nextSection || undefined)?.intermediateStops;
const timeAndPlace = intermediateStops
? intermediateStops[nextStep.intermediateStopId].departure
: (currentSection || undefined)?.arrival;
if (timeAndPlace) {
nextReachableLocation = {
lat: timeAndPlace.place.location.lat,
lng: timeAndPlace.place.location.lng,
timestamp: new Date(timeAndPlace.time),
};
}
}
}
async function simulateNextStep() {
async function skipToNextStep() {
if ($liveJourney === null) return;
try {
Expand Down Expand Up @@ -167,7 +223,11 @@
$liveJourney.isPaused = false;
calculateNewJourney = new Promise((resolve) => {
calculateNewJourney = recalculateJourney();
}
function recalculateJourney() {
return new Promise((resolve) => {
if ($liveJourney == null) {
resolve(null);
return;
Expand Down Expand Up @@ -285,7 +345,11 @@
>
{#if $liveJourney.isPaused}
<SupportBox
text={currentSupportBoxText + " " + nextReachableLocation?.lat + " " + nextReachableLocation?.lng}
text={currentSupportBoxText +
" " +
nextReachableLocation?.lat +
" " +
nextReachableLocation?.lng}
row={0}
type={$multiModality.primary === "auditory" ? "big" : "small"}
class="m-b-m"
Expand Down Expand Up @@ -345,15 +409,19 @@
{:else if $liveJourney.isCompleted}
<SupportBox
row={0}
text={currentSupportBoxText + " " + nextReachableLocation?.lat + " " + nextReachableLocation?.lng}
text={currentSupportBoxText +
" " +
nextReachableLocation?.lat +
" " +
nextReachableLocation?.lng}
type={$multiModality.primary === "auditory" ? "big" : "small"}
class="m-b-m"
/>
<label
text="place"
class="icon text-center fs-4xl"
on:tap={simulateNextStep}
on:tap={skipToNextStep}
row={1}
rowSpan={2}
/>
Expand All @@ -378,7 +446,11 @@
{#if currentSection.actions && currentSection.actions.length > 0}
<SupportBox
row={0}
text={currentSupportBoxText + " " + nextReachableLocation?.lat + " " + nextReachableLocation?.lng}
text={currentSupportBoxText +
" " +
nextReachableLocation?.lat +
" " +
nextReachableLocation?.lng}
type={$multiModality.primary === "auditory" ? "big" : "small"}
class="m-b-m"
/>
Expand All @@ -394,7 +466,7 @@
class="icon text-center {$multiModality.primary === 'auditory'
? 'fs-4xl'
: 'fs-3xl'}"
on:tap={simulateNextStep}
on:tap={skipToNextStep}
row={1}
/>
Expand All @@ -410,14 +482,18 @@
{:else if currentSection.intermediateStops}
<SupportBox
row={0}
text={currentSupportBoxText + " " + nextReachableLocation?.lat + " " + nextReachableLocation?.lng}
text={currentSupportBoxText +
" " +
nextReachableLocation?.lat +
" " +
nextReachableLocation?.lng}
type={$multiModality.primary === "auditory" ? "big" : "small"}
class="m-b-m"
/>
<label
class="icon text-center fs-3xl"
on:tap={simulateNextStep}
on:tap={skipToNextStep}
row={1}
text={(() => {
let id = $liveJourney.currentIntermediateStop;
Expand Down Expand Up @@ -471,7 +547,11 @@
{:else}
<SupportBox
row={0}
text={currentSupportBoxText + " " + nextReachableLocation?.lat + " " + nextReachableLocation?.lng}
text={currentSupportBoxText +
" " +
nextReachableLocation?.lat +
" " +
nextReachableLocation?.lng}
type={$multiModality.primary === "auditory" ? "big" : "small"}
class="m-b-m"
/>
Expand All @@ -480,7 +560,7 @@
text={transportTypeToIcon(currentSection.transport.mode)}
class="icon text-center fs-3xl"
row={1}
on:tap={simulateNextStep}
on:tap={skipToNextStep}
/>
<label
Expand Down

0 comments on commit 094e9cf

Please sign in to comment.