mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-15 12:04:00 +08:00
nav
This commit is contained in:
@@ -14,6 +14,16 @@ NAV_INSTRUCTION_COLLAPSED_KEY = "NavInstructionCollapsed"
|
||||
RECENT_DESTINATIONS_LIMIT = 10
|
||||
|
||||
|
||||
def normalize_route_id(value: Any) -> str | None:
|
||||
"""Return only route IDs generated by Galaxy's Mapbox route list."""
|
||||
route_id = str(value or "").strip()
|
||||
if route_id == "main":
|
||||
return route_id
|
||||
if route_id.startswith("alt-") and route_id[4:].isdigit() and int(route_id[4:]) >= 1:
|
||||
return route_id
|
||||
return None
|
||||
|
||||
|
||||
def _coerce_float(value: Any) -> float | None:
|
||||
try:
|
||||
parsed = float(value)
|
||||
@@ -62,12 +72,16 @@ def normalize_destination_payload(payload: Any) -> dict[str, Any] | None:
|
||||
if not name or latitude is None or longitude is None:
|
||||
return None
|
||||
|
||||
return {
|
||||
normalized = {
|
||||
"name": name,
|
||||
"place_name": name,
|
||||
"latitude": latitude,
|
||||
"longitude": longitude,
|
||||
}
|
||||
route_id = normalize_route_id(payload.get("routeId"))
|
||||
if route_id is not None:
|
||||
normalized["routeId"] = route_id
|
||||
return normalized
|
||||
|
||||
|
||||
def parse_destination_json(raw_value: str | bytes | dict[str, Any] | None) -> dict[str, Any] | None:
|
||||
@@ -285,6 +299,10 @@ def normalize_recent_destination_entry(entry: Any) -> dict[str, Any] | None:
|
||||
normalized["longitude"] = longitude
|
||||
normalized["name"] = place_name
|
||||
|
||||
route_id = normalize_route_id(entry.get("routeId"))
|
||||
if route_id is not None:
|
||||
normalized["routeId"] = route_id
|
||||
|
||||
return normalized
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class Navigationd:
|
||||
self._route_lock = threading.Lock()
|
||||
self._route: NavigationRoute | None = None
|
||||
self._active_destination: dict[str, object] | None = None
|
||||
self._requested_destination_key: tuple[str, float, float] | None = None
|
||||
self._requested_destination_key: tuple[str, str, float, float] | None = None
|
||||
self._route_fetch_inflight = False
|
||||
self._route_generation = 0
|
||||
self._published_route_generation = -1
|
||||
@@ -44,11 +44,12 @@ class Navigationd:
|
||||
self._last_nav_state: dict[str, object] | None = None
|
||||
|
||||
@staticmethod
|
||||
def _destination_key(destination: dict[str, object] | None) -> tuple[str, float, float] | None:
|
||||
def _destination_key(destination: dict[str, object] | None) -> tuple[str, str, float, float] | None:
|
||||
if destination is None:
|
||||
return None
|
||||
return (
|
||||
str(destination["place_name"]).casefold(),
|
||||
str(destination.get("routeId") or "main"),
|
||||
round(float(destination["latitude"]), 6),
|
||||
round(float(destination["longitude"]), 6),
|
||||
)
|
||||
|
||||
@@ -400,13 +400,15 @@ class MapboxRouteEngine:
|
||||
return None
|
||||
|
||||
end = Coordinate(float(destination["latitude"]), float(destination["longitude"]))
|
||||
route_id = str(destination.get("routeId") or "main")
|
||||
requested_route_index = int(route_id[4:]) if route_id.startswith("alt-") and route_id[4:].isdigit() else 0
|
||||
params: dict[str, str] = {
|
||||
"access_token": token,
|
||||
"geometries": "geojson",
|
||||
"steps": "true",
|
||||
"overview": "full",
|
||||
"annotations": "maxspeed",
|
||||
"alternatives": "false",
|
||||
"alternatives": "true" if requested_route_index > 0 else "false",
|
||||
"banner_instructions": "true",
|
||||
}
|
||||
if bearing is not None:
|
||||
@@ -420,7 +422,7 @@ class MapboxRouteEngine:
|
||||
return None
|
||||
|
||||
routes = data.get("routes") or []
|
||||
route = routes[0] if routes else None
|
||||
route = routes[requested_route_index] if requested_route_index < len(routes) else (routes[0] if routes else None)
|
||||
legs = route.get("legs") if route else None
|
||||
leg = legs[0] if legs else None
|
||||
if data.get("code") != "Ok" or route is None or leg is None:
|
||||
|
||||
@@ -947,7 +947,8 @@ function NavigationDestination({
|
||||
body: JSON.stringify({
|
||||
name,
|
||||
longitude: destinationCoordinates[0],
|
||||
latitude: destinationCoordinates[1]
|
||||
latitude: destinationCoordinates[1],
|
||||
routeId,
|
||||
})
|
||||
});
|
||||
await loadFavorites();
|
||||
|
||||
+12
-3
@@ -167,6 +167,8 @@ export const NavigationDestinationPanel = {
|
||||
if (savedDestination) {
|
||||
const raw = saved || nav?.destination || {}
|
||||
const savedName = String(raw?.name || raw?.text || "").trim()
|
||||
const savedRouteId = String(raw?.routeId || "main")
|
||||
this.selectedRouteId = /^(?:main|alt-[1-9]\d*)$/.test(savedRouteId) ? savedRouteId : "main"
|
||||
this.destination = { ...raw, ...savedDestination, name: savedName || labelFor(raw) || "Current destination" }
|
||||
this.query = this.destination.name
|
||||
this.navigationStarted = true
|
||||
@@ -259,6 +261,7 @@ export const NavigationDestinationPanel = {
|
||||
async chooseSuggestion(place) {
|
||||
this.searching = true
|
||||
try {
|
||||
this.selectedRouteId = "main"
|
||||
this.destination = await this.resolvePlace(place)
|
||||
this.query = this.destination.name
|
||||
this.suggestions = []
|
||||
@@ -285,11 +288,13 @@ export const NavigationDestinationPanel = {
|
||||
try {
|
||||
this.destination = place || await this.resolveQuery()
|
||||
if (!this.destination) throw new Error("Enter a destination first.")
|
||||
const selectedRouteId = this.selectedRouteId || this.routeSummary?.routeId || "main"
|
||||
this.destination = { ...this.destination, routeId: selectedRouteId }
|
||||
await api.setNavigation(this.destination)
|
||||
this.navigationStarted = true
|
||||
this.query = this.destination.name
|
||||
this.suggestions = []
|
||||
await this.previewDestination(this.destination)
|
||||
await this.previewDestination(this.destination, selectedRouteId)
|
||||
showSnackbar("Destination set.")
|
||||
} catch (e) {
|
||||
this.error = e?.message || "Failed to set destination."
|
||||
@@ -351,6 +356,7 @@ export const NavigationDestinationPanel = {
|
||||
selectRoute(route, routeId = "main") {
|
||||
if (!route) return
|
||||
this.selectedRouteId = routeId
|
||||
if (this.destination) this.destination = { ...this.destination, routeId }
|
||||
this.routeSummary = {
|
||||
distance: Number(route.distance) || 0,
|
||||
duration: Number(route.duration) || 0,
|
||||
@@ -358,7 +364,7 @@ export const NavigationDestinationPanel = {
|
||||
}
|
||||
if (this.map && this.routes.length) highlightRoute(this.map, this.routes, routeId)
|
||||
},
|
||||
async previewDestination(place) {
|
||||
async previewDestination(place, preferredRouteId = null) {
|
||||
if (!this.mapReady || !this.map || !place) return
|
||||
const mapboxgl = window.mapboxgl
|
||||
this.destinationMarker?.remove()
|
||||
@@ -374,8 +380,11 @@ export const NavigationDestinationPanel = {
|
||||
const payload = await api.mapboxDirections(this.lastPosition, place, this.mapboxPublic)
|
||||
const routes = Array.isArray(payload?.routes) ? payload.routes : []
|
||||
if (routes.length) {
|
||||
const requestedRouteId = preferredRouteId || place.routeId || this.selectedRouteId || "main"
|
||||
const selectedIndex = routes.findIndex((_, index) => this.routeId(index) === requestedRouteId)
|
||||
const selectedRouteId = selectedIndex >= 0 ? requestedRouteId : "main"
|
||||
this.routes = routes
|
||||
this.selectRoute(routes[0], "main")
|
||||
this.selectRoute(routes[selectedIndex >= 0 ? selectedIndex : 0], selectedRouteId)
|
||||
removeRouteFromMap(this.map)
|
||||
addRouteToMap(
|
||||
this.map,
|
||||
|
||||
Reference in New Issue
Block a user