MapComplete/src/UI/InputElement/Helpers/SlopeInput.svelte

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

110 lines
3.1 KiB
Svelte
Raw Normal View History

2023-12-14 16:57:47 +01:00
<script lang="ts">
import { ImmutableStore, UIEventSource } from "../../../Logic/UIEventSource"
2023-12-14 16:57:47 +01:00
import Translations from "../../i18n/Translations"
import Tr from "../../Base/Tr.svelte"
import { Orientation } from "../../../Sensors/Orientation"
import type { Feature } from "geojson"
import { GeoOperations } from "../../../Logic/GeoOperations"
import If from "../../Base/If.svelte"
import type { SpecialVisualizationState } from "../../SpecialVisualization"
2023-12-14 16:57:47 +01:00
export let value: UIEventSource<string> = new UIEventSource<string>(undefined)
2023-12-14 16:57:47 +01:00
export let mode: "degrees" | "percentage" = "percentage"
export let feature: Feature = undefined
export let state: SpecialVisualizationState = undefined
2023-12-14 16:57:47 +01:00
let featureBearing: number = 45
if (feature?.geometry?.type === "LineString") {
/* Bearing between -180 and + 180, positive is clockwise*/
featureBearing = Math.round(GeoOperations.bearing(
feature.geometry.coordinates[0],
feature.geometry.coordinates.at(-1),
))
2023-12-14 16:57:47 +01:00
}
let previewDegrees: UIEventSource<string> = new UIEventSource<string>(undefined)
let previewPercentage: UIEventSource<string> = new UIEventSource<string>(undefined)
2023-12-14 16:57:47 +01:00
function degreesToPercentage(beta: number): string {
const perc = Math.tan(beta * Math.PI / 180) * 100
const rounded = Math.round(perc / 2.5) * 2.5
2023-12-14 16:57:47 +01:00
return rounded + "%"
}
const orientation = Orientation.singleton
orientation.startMeasurements()
const alpha = orientation.alpha
const beta = orientation.beta
2023-12-14 16:57:47 +01:00
let gotMeasurement = orientation.gotMeasurement
2023-12-14 16:57:47 +01:00
let valuesign = alpha.map(phoneBearing => {
if (featureBearing === undefined) {
return 1
}
// are we going _with_ or _against_ the direction of the feature?
2023-12-14 16:57:47 +01:00
if (featureBearing < 0) {
featureBearing += 360
}
let relativeAngle = Math.abs(featureBearing - phoneBearing) % 360
2023-12-14 16:57:47 +01:00
if (relativeAngle < 90 || relativeAngle > 270) {
return 1
2023-12-14 16:57:47 +01:00
} else {
return -1
2023-12-14 16:57:47 +01:00
}
})
2023-12-14 16:57:47 +01:00
beta.map(beta => {
// As one moves forward on a way, a positive incline gets higher, and a negative incline gets lower.
let valueSign = valuesign.data
2023-12-14 16:57:47 +01:00
if (mode === "degrees") {
value.setData(valueSign * beta + "°")
2023-12-14 16:57:47 +01:00
} else {
value.setData(degreesToPercentage(valueSign * beta))
2023-12-14 16:57:47 +01:00
}
previewDegrees.setData(beta + "°")
previewPercentage.setData(degreesToPercentage(beta))
}, [valuesign, beta])
2023-12-14 16:57:47 +01:00
</script>
2023-12-14 18:06:07 +01:00
{#if $gotMeasurement}
2023-12-14 16:57:47 +01:00
<div class="flex flex-col m-2">
<div class="flex w-full">
<div class="font-bold w-full flex justify-around items-center text-5xl">
<div>
{$previewDegrees}
</div>
<div>
{$previewPercentage}
2023-12-14 16:57:47 +01:00
</div>
</div>
</div>
<div>
<Tr t={Translations.t.validation.slope.inputExplanation} />
</div>
<If condition={state?.featureSwitchIsTesting ?? new ImmutableStore(true)}>
<span class="subtle">
Way: {featureBearing}°, compass: {$alpha}°, diff: {(featureBearing - $alpha)}
{#if $valuesign === 1}
Forward
{:else}
Backward
{/if}
</span>
</If>
2023-12-14 16:57:47 +01:00
</div>
{/if}