Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
ferrostarCore.profile = "bicycle";

ferrostarMap.map = mapInstance;
ferrostarMap.system = "imperial";
ferrostarMap.maxDecimalPlaces = 2;

// Create a search control.
const searchBox = new MapLibreSearchControl({
Expand Down
10 changes: 5 additions & 5 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"lint:fix": "npm run lint -- --fix"
},
"dependencies": {
"@maptimy/platform-formatters": "^0.6.0",
"@maptimy/platform-formatters": "^0.6.1",
"@stadiamaps/ferrostar": "file:../common/ferrostar/pkg",
"lit": "^3.2.1",
"maplibre-gl": "^4.5.0 || ^5"
Expand Down
80 changes: 59 additions & 21 deletions web/src/ferrostar-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ import { TripState } from "@stadiamaps/ferrostar";
import "./instructions-view";
import "./trip-progress-view";
import { StateProvider as StateProvider } from "./types";
import { DistanceSystem } from "@maptimy/platform-formatters";

const allowedSystems: Array<DistanceSystem> = [
"metric",
"imperial",
"imperialWithYards",
];

const distanceSystemConverter = {
fromAttribute(value: string | null): DistanceSystem | null {
if (!value) return null;

if (allowedSystems.includes(value as DistanceSystem)) {
return value as DistanceSystem;
}
throw new Error(`Invalid distance system: ${value}`);
},
toAttribute(value: DistanceSystem): string {
return value;
},
};

/**
* A MapLibre-based map component.
Expand Down Expand Up @@ -68,6 +89,18 @@ export class FerrostarMap extends LitElement {
@property({ type: Boolean })
addGeolocateControl: boolean = true;

@property({ converter: distanceSystemConverter })
system?: DistanceSystem;

/**
* Specifies the maximum number of digits allowed after the decimal point
* when formatting distance. This helps control the precision of fractional values.
*
* Example: For a value of 2, the number 3.1415 would be rounded as 3.14.
*/
@property({ type: Number })
maxDecimalPlaces?: number;

/**
* A callback function that is invoked when navigation is stopped.
* Optional: This function can be provided by the StateProvider.
Expand Down Expand Up @@ -390,28 +423,33 @@ export class FerrostarMap extends LitElement {
</style>
<div id="container">
<div id="map">
<slot></slot>
<!-- Fix names/ids; currently this is a breaking change -->
<div id="overlay">
${this.showNavigationUI
? html`
<instructions-view
.tripState=${this.tripState}
.system=${this.system}
.maxDecimalPlaces="${this.maxDecimalPlaces}"
></instructions-view>
<div id="bottom-component">
<trip-progress-view
.tripState=${this.tripState}
.system=${this.system}
.maxDecimalPlaces="${this.maxDecimalPlaces}"
></trip-progress-view>
<button
id="stop-button"
@click=${this.handleStopNavigation}
?hidden=${!this.tripState}
>
<img src=${CloseSvg} alt="Stop navigation" class="icon" />
</button>
</div>
`
: ""}
</div>
</div>

${this.showNavigationUI
? html`
<instructions-view
.tripState=${this.tripState}
></instructions-view>
<div id="bottom-component">
<trip-progress-view
.tripState=${this.tripState}
></trip-progress-view>
<button
id="stop-button"
@click=${this.handleStopNavigation}
?hidden=${!this.tripState}
>
<img src=${CloseSvg} alt="Stop navigation" class="icon" />
</button>
</div>
`
: ""}
</div>
`;
}
Expand Down
23 changes: 23 additions & 0 deletions web/src/formatting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
DistanceSystem,
LocalizedDistanceFormatter,
} from "@maptimy/platform-formatters";

const DistanceFormatter = LocalizedDistanceFormatter();

export function formatDistance(
distanceMeters: number,
system: DistanceSystem = "metric",
desiredMaxDecimalPlaces: number = 2,
): string {
const THRESHOLDS: Record<DistanceSystem, number> = {
metric: 1000,
imperial: 1609.34, // 1 mile
imperialWithYards: 1609.34, // 1 mile
};

const exceedsThreshold = distanceMeters > THRESHOLDS[system];
const decimalPlaces = exceedsThreshold ? desiredMaxDecimalPlaces : 0;

return DistanceFormatter.format(distanceMeters, system, decimalPlaces);
}
15 changes: 11 additions & 4 deletions web/src/instructions-view.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { LitElement, css, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { LocalizedDistanceFormatter } from "@maptimy/platform-formatters";
import { DistanceSystem } from "@maptimy/platform-formatters";
import "./maneuver-image";

const DistanceFormatter = LocalizedDistanceFormatter();
import { formatDistance } from "./formatting";

@customElement("instructions-view")
export class InstructionsView extends LitElement {
@property()
tripState: any = null;

@property()
system: DistanceSystem = "metric";

@property()
maxDecimalPlaces = 2;

static styles = [
css`
.instructions-view-card {
Expand Down Expand Up @@ -63,8 +68,10 @@ export class InstructionsView extends LitElement {
${this.tripState.Navigating.visualInstruction.primaryContent.text}
</p>
<p class="instruction-text">
${DistanceFormatter.format(
${formatDistance(
this.tripState.Navigating.progress.distanceToNextManeuver,
this.system,
this.maxDecimalPlaces,
)}
</p>
</div>
Expand Down
20 changes: 17 additions & 3 deletions web/src/trip-progress-view.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import {
LocalizedDurationFormatter,
LocalizedDistanceFormatter,
DistanceSystem,
} from "@maptimy/platform-formatters";
import { LitElement, css, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { formatDistance } from "./formatting";

const DurationFormatter = LocalizedDurationFormatter();
const DistanceFormatter = LocalizedDistanceFormatter();

@customElement("trip-progress-view")
export class TripProgressView extends LitElement {
@property()
tripState: any = null;

@property()
system: DistanceSystem = "metric";

/**
* Specifies the maximum number of digits allowed after the decimal point
* when formatting distance. This helps control the precision of fractional values.
*
* Example: For a value of 2, the number 3.1415 would be rounded as 3.14.
*/
@property()
maxDecimalPlaces = 2;

static styles = [
css`
.progress-view-card {
Expand Down Expand Up @@ -65,8 +77,10 @@ export class TripProgressView extends LitElement {
)}
</p>
<p class="arrival-text">
${DistanceFormatter.format(
${formatDistance(
this.tripState.Navigating.progress.distanceRemaining,
this.system,
this.maxDecimalPlaces,
)}
</p>
</div>
Expand Down
Loading